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. 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,

  2. 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.

  3. 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.

  4. 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)!.

Leave a Reply

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