Accessibility Links

Search Blink-Design

Using jQuery Ajax to send and recieve HTML form data

I’ve focused on Ajax quite a bit in recent posts and I’ve decided to wrap it up with a detailed breakdown on how I implemented jQuery Ajax functionality on the Interlopers portfolio pages.

You could be thinking “Simon, why don’t you just marry jQuery if you love it so much?” but in my defence I would like to point out that writing Ajax with vanilla Javascript is a chore like no other. The simple case of setting up a new XMLHttpRequest(); takes a good twenty lines of code on it’s own (to account for IE) so if you want Ajax on your site and you don’t want to pull your hair out then I recommend using a library and jQuery fits the bill perfectly.

Use it wisely

The only problem with having easy access to Ajax is the desire to spam it everywhere (hello, Facebook) and fill your site with it. You have to remember that it isn’t always necessary but it can really enhance certain aspects of a site. Secondly, it’s best practice to ensure your site can perform normally and then simply layer on Ajax to enhance the experience.

The focus point of this blog post is the Interlopers portfolio page. If you head over and have a glance you’ll see that it lists members’ portfolios in a table format and provides the user with three dropdowns that can be used to filter the results. If you use it without JS enabled you’ll see that when a user submits a new search it will reload the page and then display the new list of results.

What would be nice is if the results were updated without having to load the whole page again. Step in Ajax.

The jQuery Ajax function

If you spend a bit of time looking around the jQuery documentation you’ll see that there are a few different types of the Ajax function. Simpler versions such as .post();, .get(); and .load(); exist.

However the lower level version is a bit more complicated but allows you much more control and I will demonstrate it in this example. It basically looks like this:


$.ajax({
	type: "POST",
	url: "file.php",
	data: "name=Simon&surname=Smith",
	dataType: "html",
	success: function(data){
		// do something with the response
	}
});

So that’s a really basic version of the function. You simply specify how it will be sent (type), the file you want to send the data too (url), the data itself (data), the type of data (dataType) and then have a function to deal with the response (success). On top of this are plenty of other options for dealing with other aspects.

Enhancing the portfolio page

I know that the portfolio page works fine with no Ajax enhancements so I can relax when it comes to graceful degradation. What do I need to do next?

I’ll need to run the Ajax function when the form submits (obviously) and stop the form from actually posting to the page so that the page doesn’t reload. I’ll also need to gather all the form data into a single string and send it over to the PHP file. It would be nice to add a loading spinner so the user knows something is happening so I’ll create a spinner as the Ajax request begins and then remove it when it’s finished.

Finally I’ll grab the new table results from the response and update the page.

Collecting the form data

If you use HTML forms with the POST method then you won’t see what is being sent to the server but by switching to the GET method it will reveal the form data in the URL address bar. This is the kind of format we need to construct in the Ajax function so it can be sent over to the server. For this reason it’s advisable to refrain from sending sensitive data via Ajax.

Say we had two form inputs for first and second name, we’d need to collect those data fields first.


var firstName = $('#fn').val();
var secondName = $('#ln').val(); 

Then we would apply them to the data property in the Ajax function:


data: "fn="+ firstName +"& ln="+ secondName,

That works fine but it can be a bit tiring if your form has many inputs. Wouldn’t it be nice if we could do this automatically?

Well good news is that you can, by using the serialize(); function. It’s always worth assigning the results to a variable and then alerting it into the browser so you can see exactly what is being sent to the server.

Let’s get on with it!

Right, get the submit function sorted first and set it to return false; to prevent the page reloading:


$('#portfolio-search').submit(function() {

	return false;
});

The first thing I’ll do is serialize the form and store it in a variable and also I’ll grab the action attribute from the form and keep that in a variable as well. Then I don’t need to
update the script if the destination of the form changes:


var str = $(this).serialize();
var path = $(this).attr('action');

Time to bring in the Ajax function and pop in my two variables. I’ll add to this gradually so I can explain it easily.


$.ajax({
	type: "POST",
	url: path,
	data: str,
	dataType: "html",
	success: function(data){
		
	}
});	

The first thing to do is deal with the returned data, let’s add to the success stage.

The results are inside a div with an id of portfolio-wrap so I’ll completely empty that div before I add anything else in.


$('#portfolio-wrap').empty();

It’s worth noting that when we make this Ajax call the response will be the complete HTML document from the server. Now obviously I’m only interested in the results part of the document and as I know they are contained with #portfolio-wrap I can search the response for that element and assign it to a variable.


$('#portfolio-wrap').empty();
var response = $(data).find('#portfolio-wrap').html();

Essentially I’m saying “Look through the data variable (this contains the Ajax server response i.e the HTML document), find the #portfolio-wrap element and grab the html from it. Then assign it to the variable ‘response’.

So I’ve found my data, but what do I do with it?

To give the user a bit of visual feedback I’ll hide the container for the results, add the HTML into the container and then fade it in.


$('#portfolio-wrap').empty();
var response = $(data).find('#portfolio-wrap').html();
$('#portfolio-wrap').hide().html(response).fadeIn();

How does it look so far?


$('#portfolio-search').submit(function() {
	var str = $(this).serialize();
	var path = $(this).attr('action');
	
	$.ajax({
		type: "POST",
		url: path,
		data: str,
		dataType: "html",
		success: function(data){
			$('#portfolio-wrap').empty();
			var response = $(data).find('#portfolio-wrap').html();
			$('#portfolio-wrap').hide().html(response).fadeIn();
		}
	});
	return false;
});	

So there we go! In those small lines of code we can send our form data to the server, return the new results and then update the page asynchronously.

Adding a spinner

The only problem is the delay in recieving the data may confuse the user so we should give a kind of notification that something is happening. First thing to do is grab an Ajax spinner and then upload it to your FTP.

One option of the Ajax function is beforeSend which will allow us to perform a function whilst the data transfer is taking place. In this case we’ll create a loading image and insert it into the DOM.


beforeSend: function(){ 
	$('#portfolio-search input[type=submit]').after('<div id="portfolio-loading"><img src="images/site/portfolio-loader.gif" /></div>');
},

Obviously once the Ajax request has finished I’d like to get rid of the spinner so I can simply add that to the success option.


$('#portfolio-loading').remove();

And we’re done!


$('#portfolio-search').submit(function() {
	var str = $(this).serialize();
	var path = $(this).attr('action');
	
	$.ajax({
		type: "POST",
		url: path,
		data: str,
		beforeSend: function(){ 
			$('#portfolio-search input[type=submit]').after('<div id="portfolio-loading"><img src="images/site/portfolio-loader.gif" /></div>');
		},
		dataType: "html",
		success: function(data){
			$('#portfolio-wrap').empty();
			var response = $(data).find('#portfolio-wrap').html();
			$('#portfolio-wrap').hide().html(response).fadeIn();
			$('#portfolio-loading').remove();
		}
	});
	return false;
});	

After a mammoth post we’re done! I hope that helps explain the Ajax function a bit more because I certainly struggled to find a decent post that deals with returning the server response when it’s a HTML page.

Enjoy!

Related links

Posted on Friday, July 10th 2009 and there are 12 comments

Categories: jQuery, Tricks n Tips, Web Stuff

12 Comments

Contribute

Fields marked with * are required. Your email will not be shown.

  • Please enter the word you see in the image below: