It is often the case where you have a form in your HTML, and you want to submit either all or part of it via AJAX, rather than via standard HTTP GET/ POST.
You can easily do this in jQuery using the serialize()
method, which, when called on a jQuery object containing either a form element or form controls (<input />
‘s, <select>
‘s etc.), will return a URL-encoded string.
Example HTML:
<form id="the-form">
<input name="username" type="text" value="mattlunn" />
<input name="password" type="password" value="pass1234" />
</form>
Example JavaScript:
alert($('#the-form').serialize()); // username=mattlunn&password=pass1234
Try it yourself in this jsFiddle.
This URL-encoded string can be used directly as the GET query string, or as your POST body, so all that is left is to construct a jQuery AJAX request, passing this string as the content
of the request:
jQuery.ajax({
url: '/some/endpoint.php',
method: 'GET',
data: $('#the-form').serialize()
}).done(function (response) {
// Do something with the response
}).fail(function () {
// Whoops; show an error.
});
You might find this snippet of jQuery code a good starting point for implementing AJAX forms on your website. It copies the method
and target
from the <form />
control, and makes the AJAX request for you.
/**
* Utility function to help submit forms/ form controls via AJAX.
* @param selector: Optional. Parameter passed to find() to restrict which elements are serialized. Default is to return all elements
* @param success: Required. A function to be executed when the AJAX request completes. Arguments are standard AJAX args. 'this' is the form.
* @param error: Required. A function to be executed when the AJAX request fails. Arguments are standard AJAX args. 'this' is the form.
*/
jQuery.fn.ajaxify = function (selector, success, error) {
// Handle the optional case of selector.
if (arguments.length === 2) {
error = success;
success = selector;
selector = undefined;
}
return this.on('submit', function (e) {
// Copy the options from the '<form />' control.
jQuery.ajax({
url: this.action,
method: this.method || 'GET',
data: (typeof selector === 'undefined' ? $(this).serialize() : $(this).find(selector).serialize())
}).done(jQuery.proxy(success, this)).fail(jQuery.proxy(error, this));
e.preventDefault(); // Don't forget to stop the form from being submitted the "normal" way.
});
};
The above function can be used like so;
jQuery(document).ready(function ($) {
$('form').ajaxify(function (response) {
// Handle a successful submission
}, function (xhr, error) {
// Handle an error'd submission
})
});
If you’re interested in reading further, you may want to check out the definition for a “successful control”; as only these types of elements will be contained in the string returned by serialize()
. Furthermore, you may also want to checkout the jQuery plugin “forms”, which is a plugin designed to bring unobtrusive AJAX to your forms.
Thank you for this. A nice simple way of altering a form to submit via AJAX. I’m using your code with a rails generated form, and one tweak I need to make was to change:
url: this.target,
to
url: this.action,
Hi Rob. Glad you found the article useful! Thanks for noticing the target/ action typo… it’s a typo I’ve made 1,000 times too often :P. I’ve updated the article accordingly.
Ah! I thought it was just me.
Nice post! I have a question. I’m trying to build a form that takes the input field and inserts it into the Action URL before it gets submitted. I’m trying to figure out a way to remove the ?name= aspect in the URL, because the API requires the GET request to be a specific form.
Example:
If they type in “fast”, I need the url to be:
http://some-api.com/fast/
and not
http://some-api.com/?name=fast
Thoughts?
I think the answer is somewhere in your post here, but I can’t seen to parse it out.
Hi Patrick. That’s a little outside the scope of the post. How would you want the URL to be build if you had multiple form controls on the page? E.g.
name=foo&title=bar
; how do you determine if you want http://some-api.com/foo/bar or http://some-api.com/bar/foo?If you want to post a question on http://stackoverflow.com, I’d be happy to follow up an answer on there; ping me a link to the question either on twitter (@mattlunn), or email (contact@mattlunn.me.uk)!.