If you’re developing a single-page application or practicing progressive enhancement techniques you’ll often need to intercept form submissions and translate them to an Ajax call. Let’s look at a typical form:

<form id="myform" action="webservice.php" method="post">

<input type="email" name="email" />

<select name="job">
<option value="">role</option>
<option>web developer</option>
<option>IT professional</option>
<option>other</option>
</select>

<input type="checkbox" name="freelancer" /> are you a freelancer?

<input type="radio" name="experience" value="4" /> less than 5 year's experience
<input type="radio" name="experience" value="5" /> 5 or more year's experience

<textarea name="comments" rows="3" cols="60"></textarea>

<button type="submit">Submit</button>

</form>

Form interception is straight-forward in jQuery because you can pass the form node to the serialize method to extract all field data, e.g.

$("myform").on("submit", function(e) {
	e.preventDefault();
	$.post(this.action, $(this).serialize());
});

If you’re using raw JavaScript, you’ll need to implement similar functionality yourself. You can either manually fetch every field one-by-one or implement a generic form element data extraction loop:

document.getElementById("myform").onsubmit = function(e) {

	e.preventDefault();
	
	var f = e.target,
		formData = '',
		xhr = new XMLHttpRequest();
	
	// fetch form values
	for (var i = 0, d, v; i < f.elements.length; i++) {
		d = f.elements[i];
		if (d.name && d.value) {
			v = (d.type == "checkbox" || d.type == "radio" ? (d.checked ? d.value : '') : d.value);
			if (v) formData += d.name + "=" + escape(v) + "&";
		}
	}
	
	xhr.open("POST", f.action);
	xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8");
	xhr.send(formData);

}

That’s a reasonable quantity of code even if you define it in a re-usable function. You may also require additional checks if you’ve disabled fields or made them read-only.

Fortunately, a little-known FormData interface has been added to XMLHttpRequest2 which handles much of the hard work for you. Let’s re-write our JavaScript submit handler to use it:

document.getElementById("myform").onsubmit = function(e) {

	e.preventDefault();
	
	var f = e.target,
		formData = new FormData(f),
		xhr = new XMLHttpRequest();
	
	xhr.open("POST", f.action);
	xhr.send(formData);
}

That’s much simpler — it’s also faster and easier to read than the jQuery alternative.

The FormData constructor can be passed a form element node; this instructs it to retrieve and encode all field name/value pairs. You’ll also notice we didn’t need to explicitly set xhr.setRequestHeader("Content-Type") since data is sent in the same format defined in the form’s submit() method. An encoding of multipart/form-data is also used so you can upload files.

If no form element is passed to the constructor, an empty FormData object is created. Which ever way it’s initialized, you can append additional name/value pairs using the append method, e.g.

var formData = new FormData();
formData.append("name", "value");
formData.append("a", 1);
formData.append("b", 2);

If the value is a File or Blob, a third parameter can specify an optional filename.

FormData is supported in all modern browsers. Only IE9 and below will cause trouble but, if you’re supporting the older versions of IE, you’ll probably be using jQuery or another library which implements its own field data extraction method.

For more information, refer to the FormData reference and Using FormData Objects on MDN.

Craig is a freelance UK web consultant who built his first page for IE2.0 in 1995. Since that time he's been advocating standards, accessibility, and best-practice HTML5 techniques. He's written more than 1,000 articles for SitePoint and you can find him @craigbuckler

Free Guide:

How to Choose the Right Charting Library for Your Application

How do you make sure that the charting library you choose has everything you need? Sign up to receive this detailed guide from FusionCharts, which explores all the factors you need to consider before making the decision.


No Reader comments

Learn JavaScript for free!
Free course: Introduction to JavaScript

Yours when you take up a free 14-day SitePoint Premium trial.