When creating modern web apps you can end up spending a lot of your time dealing with “AJAXifying” forms. Thanks to popularisation of Javascript frameworks this has become far simpler than it used to be. However as web developers we need to be looking at ways of streamlining the process and creating maintainable, elegant and reusable code. This article will explain how to use jQuery and PHP to make using AJAX in your web apps a far simpler affair.
HTML Forms
One of the main problems with “AJAXifying” a form is that it doesn’t degrade nicely. If a user has Javascript turned off, all of a sudden your form’s are unusable. So what we ideally want to do is have perfectly normal working HTML forms that submit things to a PHP script, then drop some Javascript on top so that only users with Javascript turned on will get the benefit without punishing the minority. For those who are technically educated we want the Javascript to be completely decoupled from the HTML and PHP.
So when creating our HMTL forms we just create a bog standard working form:
<form id="some_form" method="post" action="process.php"> <input type="text" id="data" name="data" value="" /> <input type="submit" value="Submit" /> </form>
The PHP
The only downside to the process we are going to create here is that messaging has to be done in two different ways. This means the PHP has to account for both AJAX and non-AJAX requests and the different ways they pass data. Unfortunately at the moment there is no easy solution for this so we just have to work through it.
if(empty($_SERVER['HTTP_X_REQUESTED_WITH']) || strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) != 'xmlhttprequest') { //Do non AJAX processing here... } else { //Do AJAX processing here... }
The one thing we do want to do if we are processing an AJAX request is make the data format we return as easy to use as possible. So I recommend using JSON. Not only does jQuery have built in parsing ability for JSON but PHP also makes it very easy to format and return a JSON response.
$response = array(); $response['error'] = true; $response['message'] = ''; //Do some processing. If there is an error... $response['message'] = 'This is an Error returned by the server'; //... else ... $response['data'] = $data; $response['error'] = false; echo json_encode($response);
Here we use a simple array with an “error” boolean value and a “message”. You can add any other data you want to the array (like the “data” we added above) and echo an output using PHP’s json_encode function. It’s that simple. You’ll see why it’s worth doing this when we get into the Javascript below.
The Javascript
Remember what we are trying to do here is make the Javascript completely decoupled from the HTML and PHP. So what we are going to do is rig up all of the forms on the page to automatically be submitted using AJAX and fire off events for each form when something happens. This way we can simply hook into these form events to process what is happening.
Note that below we are using the jQuery Form plugin which provides us with the lovely ajaxSubmit function.
$("form").submit(function(e) { e.preventDefault(); var form = $(this); form.ajaxSubmit({ dataType: 'json', beforeSubmit: function() { var event = jQuery.Event('form:beforeSubmit'); form.trigger(event); if(event.isPropagationStopped()) return false; }, beforeSend: function() { form.trigger('form:beforeSend'); }, success: function(json) { form.trigger('form:success', [json]); }, error: function(response, status, error) { form.trigger('form:error', [response, status, error]); }, complete: function() { form.trigger('form:complete'); } }); return false; });
As you can see this small piece of Javascript rigs up all the forms on the page to be submitted using AJAX and trigger certain events during the process. The beforeSubmit event is a bit more complex as we want to be able to cancel the AJAX request in the event of form validation failing. So this is the Javascript we just drop into the page. Totally decoupled.
“But what do we do with it?” I hear you asking. Well it means that now all you have to do is hook in to those events for each form if you want to do some something with it. For example:
$('#some_form') .bind('form:beforeSubmit', function(event){ //Do your validation here... if(!validated){ event.stopPropagation(); } }) .bind('form:beforeSend', function(){ //Show a loading message... }) .bind('form:success', function(event, response){ if(response.error){ alert('<strong>Error:</strong> ' + response.message); } else { //Update UI... } }) .bind('form:error', function(event, response, status, error){ alert('<strong>Error:</strong> An error occurred while trying to save'); }) .bind('form:complete', function(){ //Hide loading message... });
How cool is that? As you can see this makes attaching and processing form submissions via AJAX far easier. You don’t even have to use all of the events, only use the ones you need.
Two things to note. We use the event.stopPropagation() function in the “:beforeSubmit” event if we need to cancel the request. Also in the “:success” event we can use response.error and response.message. This is because we formatted our response in JSON in the PHP above. Any data that you put the PHP response array can now be access in the Javascript using “response.{data}”.
Conclusion
I would encourage all serious web developers using AJAX in their web apps to consider using a streamlined approach like the one outlined here when “AJAXifying” their forms. Clean, maintainable, reusable and elegant.
Credit where credit is due, this article builds upon the jQuery Evented Programming Primer article over at orderedlist.com and would not be here if it wasn’t for amazing guys like them helping us out by sharing their knowledge.
Well written article! Very helpful.
Great article.
Hey Gilbert,
your article and work is great !
thanks for the sharing
keep up good things.