« Back to demos index

Integrate with the jQuery validation plugin

Often times you have a form with client-side validation rules and some upload fields. You only want to trigger the uploads once the user has filled out the form in a way that fulfills all validation rules.

This can be tricky as there are numerous submit handlers involved. This demo and especially the javascript code for it show you how to do it. The source code is annotated. The comments contain all the details. You can use it right away and enhance it with your own progress bar using the onProgress callback.

"steps": {
  "resize": {
    "robot": "/image/resize",
    "use": ":original",
    "width": 130,
    "height": 130,
    "result": true
  }
}
// Step 1: Load/include jQuery, our jQuery Transloadit plugin, and jQuery validate
// ...

// Step 2: Use the following additional Transloadit Uploader plugin that handles the integration with jQuery validate
// Put it into a different file and include it on your page
(function($) {
  function TransloaditUploader() {}

  TransloaditUploader.prototype.init = function($form) {
    this.$form          = $form;
    this.$files         = this.$form.find('input[type=file]');
    this.uploadBound    = false;
    this.errorTimeout   = 15000;
    this.gotStartEvent  = false;
    this.uploadFinished = false;

    this.bindValidate();
  };

  TransloaditUploader.prototype.bindValidate = function() {
    var self = this;

    // add our validation rules
    this.$form.validate({
      rules: {
        'name': {
          required: true,
          minlength: 2
        },
        'test_file': {
          required: true,
          minlength: 2
        },
      },
      submitHandler: function(form) {
        // this is the most important part
        // if the upload wasn't finished yet, we just trigger the upload,
        // otherwise we submit the form directly and have previously unbound
        // the transloadit submit handler
        if (!self.uploadFinished) {
          self.triggerUpload();
        } else {
          form.submit();
        }
      },
    });

    // if the user chooses a file, remove the error message
    // for that file input field
    self.$files.change(function() {
      if ($(this).val() != '') {
        var $parent = $(this).parent();
        $parent.removeClass('error');
        $parent.find('label.error').remove();
      }
    });
  };

  TransloaditUploader.prototype.triggerUpload = function() {
    var self = this;

    // now bind our transloadit jquery plugin
    this.bindUpload();

    // only trigger the Transloadit upload, no other submit event
    this.$form.trigger('submit.transloadit');

    // if the upload wasn't started within a certain time
    // then we have a connection problem and should show that
    setTimeout(function() {
      if (!self.gotStartEvent) {
        self.uploadError();
      }
    }, self.errorTimeout);
  };

  TransloaditUploader.prototype.bindUpload = function() {
    this.uploadBound = true;
    var assemblyId   = null;
    var self         = this;

    this.$form.transloadit({
      wait: false,
      autoSubmit: true,
      onStart: function(obj) {
        self.gotStartEvent = true;
        assemblyId = obj.assembly_id;
      },
      onError: function(obj) {
        self.uploadError();
      },
      onResult: function(step, result, assembly) {
        if (assembly.ok == 'ASSEMBLY_UPLOADING') {
          return;
        }

        // when we are done uploading, stop all transloadit actions
        // and, important, unbind its submit handler!
        self.uploadFinished = true;
        self.$form.transloadit('stop');
        self.$form.unbind('submit.transloadit');
      }
    });
  };

  TransloaditUploader.prototype.uploadError = function() {
    // if we have an upload error stop all transloadit processing
    // and trigger an alert
    this.$form.transloadit('stop');
    alert('Upload error');
  };

  $.fn.transloaditUpload = function() {
    this.each(function() {
      var upload = new TransloaditUploader();
      upload.init($(this));
    });

    return this;
  };
})(jQuery);

// Step 3: Initialize your form with the uploader plugin when the dom is ready
$(function() {
  $('form').transloaditUpload();
});

The form

For demos we allow a maximum of 30MB.

This form is html5-multiupload enabled. If your browser supports it, you can select multiple files and execute the template with them.