Submitting a form as an AJAX request using jQuery

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.

15 thoughts on “Submitting a form as an AJAX request using jQuery

  1. Pingback: Sending FormData with jQuery.ajax() | Matt

  2. Very helpful, thank you.
    One thing: You are calling jQuery.proxy with the arguments backwards, no?

    You have this:
    jQuery.proxy(this, success)).fail(jQuery.proxy(this, error));

    Docs say this:
    jQuery.proxy( function, context )

    …I flipped ’em and all works well. Thanks again!

  3. Hi Matt, great article.

    I’m a beginner with Javascript (and JQuery), and came across your blog post when I was searching on Google for a method of doing form submits without a page reload. Your utility function sounds like it will do the job for me, but I’m not quite sure about how to use it. This is what I’m (naively) attempting at present:

    http://pastebin.com/YkKN63se

    As far as I can tell the form is being submitted in the “traditional” way, though I can tell (by sticking an alert in there) that processing reaches the “return this.on” part at least when I click my button.
    But, the AJAX stuff doesn’t appear to fire, and the same for preventDefault, but I’m obviously doing something very wrong. Any tips? Sorry for the huge code snippet, but thank you very much in advance for any help!

  4. Hi Alan,

    You can call the utility function simply by using jQuery('form').ajaxify('input', success, error);. You might want to give your form an ID, and then use that to target the form, in the case you’ve got multiple on your page.

    http://pastebin.com/YTQ9mRKb

    The ajaxify code also had a small bug which Ash noticed, so I’ve fixed that in the paste as well.

    There’s also no need to call ajaxify() in a click handler for .button, as the ajaxify utility hooks into the submit event automatically.

    You should be good to go with http://pastebin.com/YTQ9mRKb :).

Leave a Reply

Your email address will not be published. Required fields are marked *