Friday, November 19, 2010

jQuery Ajax script for multipart/form-data POST method

So, I searched an eternity for a script that uses AJAX to post a HTML form using multipart/form-data, dynamically. AJAX, to the best of my knowledge, does not have any built in support to create the multipart from the HTML elements in the form. Frustrated, I whipped up this script.

Suppose, you have multiple forms inside a HTML page. The forms need to use the POST method with the enctype set to multipart/form-data:

Example HTML,


The script follows the following algorithm:

a) On submit, call form submit handler.
b) Retrieve url information from the action attribute of the form element.
c) For ever element in the form, create its respective multipart.
d) Combine multiparts and use AJAX functions to POST the form.

All you need to do to run this script, is link your HTML code to the jQuery library and add this script to the head. Voila!! You can then POST your forms using multiparts :).

Note: This code as of now does NOT support file uploads, I will whip that part up when I need it. I hope this helps someone.

//When the DOM is ready

$(document).ready(function(){

//When the submit button is clicked

$('form').submit(function(event) {

strPath =$('form').attr('action')

//Check if the action attribute is set

if(strPath){

//This is to prevent the default submit behaviour of button

event.preventDefault()

//Get content from form as multipart

strContent = $.getMultipartData('#'+this.id);

//Do ajax call for posting to server

$.ajax({

type:'POST',

url:'',

contentType: 'multipart/form-data; boundary='+strContent[0],

data: strContent[1],

success: function(msg){

alert("data is:"+msg)

}

})

}else{

alert('Please fix action attribute in form');

}

});

});

$.getMultipartData = function(frmName){

//Start multipart formatting

var initBoundary= $.randomString();

var strBoundary = "--" + initBoundary;

var strMultipartBody = "";

var strCRLF = "\\r\\n";

//Create multipart for each element of the form

jQuery.each($(frmName).serializeArray(),function(){

strMultipartBody +=

strBoundary

+ strCRLF

+ "Content-Disposition: form-data; name=\\"" + $(this).attr('name') + "\\""

+ strCRLF

+ strCRLF

+ $(this).val()

+strCRLF;

});

//End the body by delimiting it

strMultipartBody += strBoundary + "--" + strCRLF;

//Return boundary without -- and the multipart content

return [initBoundary,strMultipartBody];

};

$.randomString = function() {

var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";

var string_length = 8;

var randomstring = '';

for (var i=0; i<string_length; i++) {

var rnum = Math.floor(Math.random() * chars.length);

randomstring += chars.substring(rnum,rnum+1);

}

return randomstring;

};