First off, make sure you name your form inputs correctly, that will make your life easier
If you do not wish to support IE8/9 for your ajax upload you can use the following:
// FormData is not supported by ie8 and 9 as far as I know
// and some others see here: http://caniuse.com/#search=FormData
// you can check for FormData support by something like this
var supportFormData = function(){
return !! window.FormData;
};
$('#form_new_product').submit(function(e) {
e.preventDefault();
var form;
// you can pass in your form element here if you have the <input> tags named correctly, like this:
form = new FormData($("#form_new_product").eq(0)) // that's the easiest way
// or you can create a FormData object and append stuff to it
form = new FormData();
// signature --> form.append(input[name], input[value])
form.append('product_name', $('#form_new_product input[name="product_name"]').val());
form.append('product_description', $('#form_new_productinput[name="product_description"]').val());
// now a file input,
form.append('product_image', $('#form_new_product input[type="file"]').eq(0).files[0], 'image.png'/*optional*/);
return $.ajax({
url: '/path/to/form/action',
type: 'POST',
data: form,
mimeType:'multipart/form-data",
contentType: false,
cache: false,
processData: false
)
.done(function(response){
// handle success
})
.fail(function(response){
// handle error
});
});
If you want to support IE8 and IE9, you may need to do some little tweaking server side as well,
and your submitForm function won't be as simple as the previous one, I would suggest using http://malsup.com/jquery/form/
like some of the other answers did, but as the plugin mentions, here
the server response header MUST be text/html
so IE8 won't trigger a file download for a JSON response (assuming you are expecting a JSON response) - basically this plugin is creating an iFrame with a form in it and submits it to the server for you. There is other solution than the text/html
like wrapping the response with a <textarea>
, check that last link I mentioned.
So, assuming you are using this plugin, here's I would do it.
var isIE = function () {
var myNav = navigator.userAgent.toLowerCase();
return (myNav.indexOf('msie') != -1) ? parseInt(myNav.split('msie')[1]) : false;
}
$('#form_new_product').submit(function(e) {
e.preventDefault();
var $form = $("#form_new_product");
var options = {
url: '/path/to/form/action',
type: "POST",
mimeType: "multipart/form-data"
};
// hack because IE lt 9 iFrame triggers a file download for a application/json response
// http://stackoverflow.com/questions/17701992/ie-iframe-doesnt-handle-application-json-response-properly
if (Reporting.util.isIE() <= 9) {
// maybe you have another contract with the server, like a custom query string or whatever
// but the server needs to return text/html
options.ContentType = "text/html";
}
// don't think this returns a promise, so you can use the options.success and options.error like that
options.success = function(response){
// handle success
};
options.error = function(response){
// handle error
};
// or you really want to return a promise, then you can
var deferred = new $.Deferred();
options.success(function(response){
deferred.resolve(response);
});
options.error(function(response){
deferred.reject(response);
})
// this will submit all of your inputs
form.ajaxSubmit(options);
return deferred;
});