Progressive Enhancement via AJAX

I have recently been curious on how a normal web site with various posts and page reloads could be improved through AJAXifying it (yes, I did mean to say that – you get what I mean) – i.e. introduce AJAX calls to improve the smoothness of the user experience and minimise page reloads in key areas of a site.

In particular, my understanding of JS frameworks such as jQuery, based on the examples I’d seen, meant that form submissions were tied to specific knowledge of the form that the event was bound to.  For instance, when you bind the onSubmit event to a particular form, the many examples out there show functions that then pull content from the form through something like the following selector:

var inputVal = $('form input[name=user]').val();

This is OK for specific cases like a registration or contact us form that tends to be unique on a page but what if there were multiple similar forms on a given page and you simply wanted to submit all the form data to the same URL as before with the standard form submission but instead through an AJAX HTTP Request?

Somehow, having this sort of specific knowledge from within the handler function didn’t feel right to me, so I set off with the goal to find out how I can get the related form data from the info that is passed to the event function handler by default, without any extra manual passing of data etc.

This led me to the jQuery Event Object (api.jquery.com/category/events/event-object/), which through the target property provides a reference to the DOM element that initiated the event a.k.a. the element that I bound the event to.  This provides the key piece of information that I was missing.

Let’s take the following HTML code snippet that has 3 similar forms on a single page as an example:

<form name="form1" action="/getSomething" method="post">
  <input type="text" name="input1" />
</form>
<form name="form2" action="/getSomethingElse" method="post">
  <input type="text" name="input2" />
</form>
<form name="form3" action="/getAnotherThing" method="post">
  <input type="text" name="input3" />
</form>

Taking the above example, we can bind the event to all three forms in one go with the following:

$('form').submit(getSomethingFunction);

As we know we are passed the event object to the handler function, we can extract the form specifics being used once within the function:

function getSomethingFunction(eventObject)
{
    var formName = eventObject.target.getAttribute('name');
    var formAction = eventObject.target.getAttribute('action');
    ...  
    return false;
}

We can then initiate our post request using the jQuery serialize() function (api.jquery.com/serialize/):

function getSomethingFunction(eventObject)
{
    var formName = eventObject.target.getAttribute('name');
    var formAction = eventObject.target.getAttribute('action');
    $.post(formAction,$('form[name='+formName+']').serialize(), callbackFunction,'json');
    return false;
}

As you can see, through the power of jQuery, it simplifies this type of challenge with only a small amount of easy to follow code, allowing you to re-use the same (pre-AJAXified) server side code.

In my real case, I added a ?format=json to the post URL when calling via AJAX so that my server side PHP script knew that it didn’t need to send a full HTML page back as a response and instead sent a JSON formatted success/failure message back.

From this small investigation, I’m now interested in understanding what frameworks are out there that facilitate this type of progressive enhancement approach and utilise a widely adopted JS library such as jQuery.  Please leave a comment if you have any tips or advice.

One thought on “Progressive Enhancement via AJAX

  1. dannybaggs

    I’ve corrected a key flaw in the original post. I initially said that you could get the name and action of the form through this code:

    var formName = eventObject.target[‘name’];
    var formAction = eventObject.target[‘action’];

    This is not the case. The name is returned but not the action and in either case, it is not the correct approach.

    The corrected code now reads:

    var formName = eventObject.target.getAttribute(‘name’);
    var formAction = eventObject.target.getAttribute(‘action’);

    Apologies and hope the update is useful.

    Dan

    Reply

Leave a Reply

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