Ko.applybindings not working with dynamic html element

I am writing some code where when the user clicks on the add file button, after success add a new row to the table that includes the upload button. This button will bind to the client of the data binding.

I am trying to apply knockoutbindings to a dynamic html string. without any consequences. From my code, I am not getting any error, but nothing happens after clicking the download button.

code

ViewModel

$(function () {

        // download section viewModel
        var viewModel = function () {
            self.downloadOrder = function (item, event) {
                var domElement = event.target;
                $.fileDownload('@Url.Action("test", "test")' + "?fileName=" + item.documentName + "&quoteNoEncrypted=" + item.quoteNoEncrypt, {

                    failCallback: function () {
                        $("<span style='position: absolute'> @TranslationService.Read("Waybill_Common_FileNoLongerExist", module, languageCode) </span>").insertAfter(domElement).fadeIn(1000, "linear", function () {
                            $(domElement).next().delay(2000).fadeOut("slow");
                        });

                    }
                });
            };

        }

      

Bindings when loading source document

        ko.applyBindings(viewModel, document.getElementById("documentSection"));
        ko.applyBindings(headerViewModel, document.getElementById("dashBoardHeader"));
        ko.applyBindings(quoteVM, document.getElementById("viewRequest"));

      

after successful upload add row to docs table and applybindings. Issue.

           $("#btncareerssubmimt").click(function () {
            $("#uploadDocumentForm").ajaxSubmit({
                type: "POST",
                success: function (data) {
                    $.each(data, function (index, file) {
                        // insert new datafile row to the table
                        $("#supporting-documents-table >tbody:last").append('<tr id=' + file.DocumentId + '><td>' + file.Title + '</td>' + '<td>' +
                            file.UploadDate + '</td>' + '<td>' + '<input type="button" value="@TranslationService.Read("Waybill_Common_DownloadTitle", module, languageCode)" data-bind="click: function(data, event){downloadOrder({quoteNoEncrypt: "@Model.QuoteNoEncrypt", documentName:' +
                            file.Title + '}, event)}" />' + '</td></tr>');

                        // get new row id
                        var rowId = $("#supporting-documents-table tr:last").attr('id');

                        // add the download knockout handler to this new row

                        ko.applyBindings(viewModel, document.getElementById(rowId));

                    })
      }):

      

any ideas? thank.

+3


source to share


2 answers


You need to re-bind the bindings, for example:

var element = document.getElementById("documentSection");
ko.cleanNode(element);
ko.applyBindings(viewModel, element);

      



But I am not suggesting doing this, as far as I remember, it is not well supported (since it does not clear the event handlers).

The correct way to do this would be to have observableArray

your supporting documents, and if you need to add logic to iterate over, think of an array and display your strings, but on success

you just need to add a new object to that observableArray

and the string will be added automatically. (a good example can be found there ).

0


source


Thanks to Vladimir's guidance, the problem was solved with observable arrays.

I added the uploadDocument function to the existing viewModel

uploadDocument: function (documentList) {
        if (documentList != null) {
           _uploadButtonDisable(true)
              // start spinner  
            var target = document.getElementById('uploadMessage');           
            var spinner = new Spinner().spin(target);                                   

                        //show spinner
            $(target).val("").show();

            $("#uploadDocumentForm").ajaxSubmit({
                type: "POST",
                success: function (data) {
                $.each(data, function (index, file) {
                    // insert new datafile row to the table
                     documentList.push(file);
                     spinner.stop(spinner);
                     $("#uploadMessage").text('@TranslationService.Read("SSP_Common_Success_Text", "SSP", languageCode)').fadeIn(1000, "linear", function () {
                     $(this).delay(2000).fadeOut("slow", function () {
                           $(this).text("");
                     });

                  });
                  _uploadButtonDisable(false)

                })

                },
                    error: function () {
                        spinner.stop(spinner);
                                $("#uploadMessage").text('@TranslationService.Read("SSP_Server_Error_UI_Text", "SSP", languageCode)').fadeIn(1000, "linear", function () {
                                    $(this).delay(2000).fadeOut("slow", function () {
                                        $(this).text("");
                                    });

                                });
                                _uploadButtonDisable(false)
                                //input.replaceWith(input.val('').clone(true));

                            }
                        });
                        var input = $("#choose-file");

                    }
                }

      

Bind the viewModel.



           var jsonModel = '@Html.Raw(JsonConvert.SerializeObject(this.Model))';
           var mvcwModel = ko.mapping.fromJSON(jsonModel);
           mvcwModel.viewModel = viewModel;

           ko.applyBindings(mvcwModel, document.getElementById("viewRequest"));

      

attach uploadDocument to uploadButton

<tr>
   <td>
  <th><input type="button" value="@TranslationService.Read("Waybill_OrderDisplay_UploadSubmit", module, languageCode)" id="btncareerssubmimt" class=" floatRight" data-bind="disable: viewModel.uploadButtonDisable, click: function(){ viewModel.uploadDocument($root.Documents);}" /></th>
   </td>
</tr>

      

0


source







All Articles