title: Knockout JS: Fileupload event
body: <p>I have this knockout js script for uploading file </p>
  
  <p>This code triggers the upload event when the user selects a file in the upload control</p>
  
  <p><strong>Upload.html</strong></p>
  
  <pre><code>    $(function() {
          var viewModel = {
              filename:  ko.observable(""),
          };
  
          ko.applyBindings(viewModel);
      });
  
  &lt;form&gt;
  &lt;input id="upload" name="upload" 
      data-bind="fileUpload: { property: 'filename', url: 'http://localhost/api/upload/PostFormData' }" 
      type="file" /&gt; 
  
  &lt;button id="submitUpload"&gt;Upload&lt;/button&gt;
  &lt;/form&gt;
  </code></pre>
  
  <p><strong>FileUpload.js</strong></p>
  
  <pre><code>ko.bindingHandlers.fileUpload = {
  init: function (element, valueAccessor) {
      $(element).after('&lt;div class="progress"&gt;&lt;div class="bar"&gt;&lt;/div&gt;&lt;div class="percent"&gt;0%&lt;/div&gt;&lt;/div&gt;&lt;div class="progressError"&gt;&lt;/div&gt;');
  },
  update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
  
  
      var options = ko.utils.unwrapObservable(valueAccessor()),
          property = ko.utils.unwrapObservable(options.property),
          url = ko.utils.unwrapObservable(options.url);
  
  
  
      if (property &amp;&amp; url) {
  
          $(element).change(function() {
              if (element.files.length) {
                  var $this = $(this),
                      fileName = $this.val();
  
                  // this uses jquery.form.js plugin
                  $(element.form).ajaxSubmit({
                      url: url,
                      type: "POST",
                      dataType: "text",
                      headers: { "Content-Disposition": "attachment; filename=" + fileName },
                      beforeSubmit: function() {
                          $(".progress").show();
                          $(".progressError").hide();
                          $(".bar").width("0%")
                          $(".percent").html("0%");
  
                      },
                      uploadProgress: function(event, position, total, percentComplete) {
                          var percentVal = percentComplete + "%";
                          $(".bar").width(percentVal)
                          $(".percent").html(percentVal);
  
                      },
                      success: function(data) {
                          //$(".progress").hide();
                          //$(".progressError").hide();
                          // set viewModel property to filename
                          $("label[for='upload']").text(data);
  
                          bindingContext.$data[property](data);
                      },
                      error: function(jqXHR, errorThrown) {
                          $(".progress").hide();
                          $("div.progressError").html(jqXHR.responseText);
                      }
                  });
              }
          });
      }
  }
  </code></pre>
  
  <p>}</p>
  
  <p>Now, I want to move the triggering of upload event to the submit button</p>
  
  <pre><code> &lt;button id="submitUpload"&gt;Upload&lt;/button&gt;
  </code></pre>
  
  <p>How to do this? Right now this is where I'm at, I just move the upload event inside the click event of the button. But it's not working, and it doesn't call the ajax request to the API.</p>
  
  <pre><code>  $('#submitUpload').click(function () {
  
              if (element.files.length) {
  
                  var $this = $(element),
                      fileName = $this.val();
                  //alert(element.form);
  
                  // this uses jquery.form.js plugin
                  $(element.form).ajaxSubmit({
                      url: url,
                      type: "POST",
                      dataType: "text", 
                      headers: { "Content-Disposition": "attachment; filename=" + fileName },
                      beforeSubmit: function() {
                          $(".progress").show();
                          $(".progressError").hide();
                          $(".bar").width("0%")
                          $(".percent").html("0%");
  
                      },
                      uploadProgress: function(event, position, total, percentComplete) {
                          var percentVal = percentComplete + "%";
                          $(".bar").width(percentVal)
                          $(".percent").html(percentVal);
  
                      },
                      success: function(data) {
                          //$(".progress").hide();
                          //$(".progressError").hide();
                          // set viewModel property to filename
                          $("label[for='upload']").text(data);
  
                          bindingContext.$data[property](data);
                      },
                      error: function(jqXHR, errorThrown) {
                          $(".progress").hide();
                          $("div.progressError").html(jqXHR.responseText);
                      }
                  });
              }
          });
  </code></pre>