Create a Ajax based Form Submission with jQuery

Written by Kevin Liew on 01 Apr 2009
415,131 Views • Tutorials

AJAX

AJAX has changed the world of web development. Look at digg, facebook and gmail, thery are good examples to show the capability of AJAX. AJAX can create a highly responsive web interface and increase the user experience.

AJAX is abbrieviated from Asynchrounous javascript and XML. It's not a new technology, but the implementation of a group of technologies to achieve a seamless interaction between client and server.

Typically, xhtml and css to present the information, javascript is used to handle user interactions, and a server side language to perform the users' requests (and normally return data in XML format, in this tutorial, we won't do that), and it all is happening in the background using the Javascript XMLHttpRequest. Javascript plays a main role tie all these technologies together and create the asynchronous interaction between client ans server.

Advantages:
  • Reduce connections and bandwidth to the server, images, scripts, stylesheets only need to be downloaded once
  • Reduce loading timew. User doesnt have to load pages again and again, it all happens in a same page!
  • Increase responsiveness and end user experiences.
Usability Guidelines:
  • Always provide feedback to user. Let user know the server is processing the request. Indicate that using message or loading icon.
  • Prepare a plan to those users without Javascript support.
Advertisement

Introduction

So, you know about the goodness of AJAX. Let's learn a simple way to implement it.

In this tutorial, we will learn form submission using jQuery without navigate out from the page. It accepts user input, processes it and sends it to a php file called "process.php". The PHP script will send a notification email to the recipient. Of course, in case browser couldn't support javascript/XMLHttpRequest, we have a second plan ready, the form will submit the data using the normal form submission.

How do we do that? Easy, we specified POST and ACTION attributes in the FORM element, if browsers couldn't support it, that will submit the form straight away. If the browsers could support it, the javascript will cancel the submit button default behaviour. And we need to code the PHP script to support both GET and POST methods and produce the result accordingly.

1. HTML

In this sample, I'll keep everything as simple as possible. This is how it looks like

<div class="block">
<div class="done">
<b>Thank you !</b> We have received your message. 
</div>
	<div class="form">
	<form method="post" action="process.php">
	<div class="element">
		<label>Name</label>
		<input type="text" name="name" class="text" />
	</div>
	<div class="element">
		<label>Email</label>
		<input type="text" name="email" class="text" />
	</div>
	<div class="element">
		<label>Website</label>
		<input type="text" name="website" class="text" />
	</div>
	<div class="element">
		<label>Comment</label>
		<textarea name="comment" class="text textarea" /></textarea>
	</div>
	<div class="element">
		
		<input type="submit" id="submit"/>
		<div class="loading"></div>
	</div>
	</form>
	</div>
</div>
<div class="clear"></div>

2. CSS

I'm using CSS to make the 2 columns layout - LABEL and Form Elements. Also, some important classes:

  • .hightlight: Error indicator. if user had not entered anything in the textfield, it will highlight it and display an error icon
  • .loading: Loading animation icon. After user clicked on submit, if no errors were found, this icon will be displayed next to the submit button
  • .done: Success message. If the form is submitted successfully, display show this class
body{text-align:center;}

.clear {clear:both}

.block {
	width:400px;
	margin:0 auto;
	text-align:left;
}
.element * {
	padding:5px; 
	margin:2px; 
	font-family:arial;
	font-size:12px;
}
.element label {
	float:left; 
	width:75px;
	font-weight:700
}
.element input.text {
	float:left; 
	width:270px;
	padding-left:20px;
}
.element .textarea {
	height:120px; 
	width:270px;
	padding-left:20px;
}
.element .hightlight {
	border:2px solid #9F1319;
	background:url(iconCaution.gif) no-repeat 2px
}
.element #submit {
	float:right;
	margin-right:10px;
}
.loading {
	float:right; 
	background:url(ajax-loader.gif) no-repeat 1px; 
	height:28px; 
	width:28px; 
	display:none;
}
.done {
	background:url(iconIdea.gif) no-repeat 2px; 
	padding-left:20px;
	font-family:arial;
	font-size:12px; 
	width:70%; 
	margin:20px auto; 
	display:none
}

3. Javascript

Finally, the Javascript code. I have added comments in each line to explain what it does.

First, we need a simple validation to ensure user has key in something. We can add more validations, like, email validation, valid character validation, length validation and so on. And it's a good practise to encode the data into URL friendly format as well.

What the code does:

  • Get user's input
  • Validate the data, if error found, add the hightlight class, and stop the script
  • If no errors were found, all text field will be disabled and format the data to be passed to jQuery ajax method
  • jQuery will appened the data to process.php, so it will look something like this:

    http://[your-website-url]/process.php?name=kevin&email=kevin@test.com&website=http://www.queness.com&comment=Testing%20of%20Ajax%20Form%20Submission

    in fact, you can execute the process.php with that url.
  • process.php will return either 1 or 0, if 1 it meant mail was sent successfully, otherwise, mail was not sent.
  • If suceed, the form will be hidden and a message is displayed.
$(document).ready(function() {
	
	//if submit button is clicked
	$('#submit').click(function () {		
		
		//Get the data from all the fields
		var name = $('input[name=name]');
		var email = $('input[name=email]');
		var website = $('input[name=website]');
		var comment = $('textarea[name=comment]');

		//Simple validation to make sure user entered something
		//If error found, add hightlight class to the text field
		if (name.val()=='') {
			name.addClass('hightlight');
			return false;
		} else name.removeClass('hightlight');
		
		if (email.val()=='') {
			email.addClass('hightlight');
			return false;
		} else email.removeClass('hightlight');
		
		if (comment.val()=='') {
			comment.addClass('hightlight');
			return false;
		} else comment.removeClass('hightlight');
		
		//organize the data properly
		var data = 'name=' + name.val() + '&email=' + email.val() + '&website='
		+ website.val() + '&comment='  + encodeURIComponent(comment.val());
		
		//disabled all the text fields
		$('.text').attr('disabled','true');
		
		//show the loading sign
		$('.loading').show();
		
		//start the ajax
		$.ajax({
			//this is the php file that processes the data and send mail
			url: "process.php",	
			
			//GET method is used
			type: "GET",

			//pass the data			
			data: data,		
			
			//Do not cache the page
			cache: false,
			
			//success
			success: function (html) {				
				//if process.php returned 1/true (send mail success)
				if (html==1) {					
					//hide the form
					$('.form').fadeOut('slow');					
					
					//show the success message
					$('.done').fadeIn('slow');
					
				//if process.php returned 0/false (send mail failed)
				} else alert('Sorry, unexpected error. Please try again later.');				
			}		
		});
		
		//cancel the submit button default behaviours
		return false;
	});	
});	

4. PHP

This PHP code can accomodate different type of submissions (POST and GET). If the user submitted the form using jQuery, process.php will get the data from GET. and if the browser couldn't run javascript, the data will be sent using POST. What it does:

  • Retrieve user's input from either GET or POST method
  • If POST, set the $post variable to 1. This is to display the message instead of return the result
  • Then, perform the server side validation if the form was submitted using POST
  • If no errors were found, organize the data into a html email template and send it to the email we have specified.
  • Display the message if POST is used. Display result (either 1 or 0) if GET is used
<?php

//Retrieve form data. 
//GET - user submitted data using AJAX
//POST - in case user does not support javascript, we'll use POST instead
$name = ($_GET['name']) ? $_GET['name'] : $_POST['name'];
$email = ($_GET['email']) ?$_GET['email'] : $_POST['email'];
$website = ($_GET['website']) ?$_GET['website'] : $_POST['website'];
$comment = ($_GET['comment']) ?$_GET['comment'] : $_POST['comment'];

//flag to indicate which method it uses. If POST set it to 1
if ($_POST) $post=1;

//Simple server side validation for POST data, of course, 
//you should validate the email
if (!$name) $errors[count($errors)] = 'Please enter your name.';
if (!$email) $errors[count($errors)] = 'Please enter your email.'; 
if (!$comment) $errors[count($errors)] = 'Please enter your comment.'; 

//if the errors array is empty, send the mail
if (!$errors) {

	//recipient - change this to your name and email
	$to = 'Your Name <your@email.com>';	
	//sender
	$from = $name . ' <' . $email . '>';
	
	//subject and the html message
	$subject = 'Comment from ' . $name;	
	$message = '
	<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
	<html xmlns="http://www.w3.org/1999/xhtml">
	<head></head>
	<body>
	<table>
		<tr><td>Name</td><td>' . $name . '</td></tr>
		<tr><td>Email</td><td>' . $email . '</td></tr>
		<tr><td>Website</td><td>' . $website . '</td></tr>
		<tr><td>Comment</td><td>' . nl2br($comment) . '</td></tr>
	</table>
	</body>
	</html>';

	//send the mail
	$result = sendmail($to, $subject, $message, $from);
	
	//if POST was used, display the message straight away
	if ($_POST) {
		if ($result) echo 'Thank you! We have received your message.';
		else echo 'Sorry, unexpected error. Please try again later';
		
	//else if GET was used, return the boolean value so that 
	//ajax script can react accordingly
	//1 means success, 0 means failed
	} else {
		echo $result;	
	}

//if the errors array has values
} else {
	//display the errors message
	for ($i=0; $i<count($errors); $i++) echo $errors[$i] . '<br/>';
	echo '<a href="form.php">Back</a>';
	exit;
}


//Simple mail function with HTML header
function sendmail($to, $subject, $message, $from) {
	$headers = "MIME-Version: 1.0" . "\r\n";
	$headers .= "Content-type:text/html;charset=iso-8859-1" . "\r\n";
	$headers .= 'From: ' . $from . "\r\n";
	
	$result = mail($to,$subject,$message,$headers);
	
	if ($result) return 1;
	else return 0;
}
?>

Conclusion

Now you know how to build a ajax based form submission that will work even if the browser doesnt support javascript using jQuery. Make sure you check out the demo and download the source code to play with it. Last but not least, I need your support :) If you like this article, please help me to promote it by adding this post into your bookmark. Or you can subscribe to my RSS for more posts. Thanks!

Demo Download
Join the discussion

Comments will be moderated and rel="nofollow" will be added to all links. You can wrap your coding with [code][/code] to make use of built-in syntax highlighter.

312 comments
kevin Admin 15 years ago
@macro, does your server support mail send function?

@gjunkie: you need to use firebug - Net tab. Click on the button and you will able to see what's wrong.
Reply
SG 15 years ago
The post is great... However I want to find out the case in which the php script sends certain arguments (and not just a boolean value).. to be displayed as the result of form submission on the same page.
Reply
USman 15 years ago
very nice tutorial i like ajax.
Reply
cherry 15 years ago
I wanted to explain my Team members on how to write effective comments for their code. But i could not give them thumb rule anytime. This is going to help me. Give me more details on this if you have.
Reply
upvc 15 years ago
Can I implement this to a WP blog? Or is it better to use an existing plugin?
Reply
kevin Admin 15 years ago
hmm, yea you actually can but you need to know some knowledge in customizing your template though. If you have some free times and wanna make a custom contact form, yea, go ahead, otherwise, a plugin will save you heaps of times!
Reply
warren 15 years ago
Thank you very much for your thoughtful comment, and for taking the trouble to post it.
Reply
Avinash 15 years ago
not working
Reply
Kevin Liew Admin 15 years ago
you must have implemented it wrongly.
Reply
Jon Ward 15 years ago
A quick question, can this handle radio buttons? If yes, how so?
Apart from that, this is working great for me, also implemented it with fancybox ajax. Thanks for the time spent developing!!
Reply
Kevin Liew Admin 15 years ago
Yes it can, just create a radio button and give it an id, name and value. And this code should work, not yet tested though, but should give you a headstart:

var testradio = $('#input#radio');

if (testradio.val()=='') {
testradio.addClass('hightlight');
return false;
} else testradio.removeClass('hightlight');

//organize the data properly
var data = 'name=' + name.val() + '&email=' + email.val() + '&website=' + website.val() + '&comment=' + encodeURIComponent(comment.val()) + '&testradio=' + testradio.val();

that should be it.. I have a better solution which use serialize() method in jQuery, I guess I will need to make a new tutorial for it, because this seems to be a lil outdated. But it still works perfectly! :)
Reply
Michael 15 years ago
I have submitted my implemented form, so many times. Sending first to a yahoo email address, but it was working sooo super slow or not at all. I thought maybe Yahoo was blocking the emails from process.php. So I changed the email address to go to my own site's domain (which is on GoDaddy). Still super slow or not working altogether. (Everything in the browser works tho: validation, submission, fades, etc). Is anyone else noticing that is it super slow or broke?
Reply
kevin Admin 15 years ago
Hi Michael, it could due to the speed of your server. I haven't heard of such problem before, so I don't think is the script itself. Can you try it on different server?
Reply
Peter 15 years ago
Hi there, great tutorial. However I can't seem to get the AJAX side of things working. Whenever I click submit on my script it takes me straight to the process.php page. But your example I downloaded and it works fine?
Reply
Kevin Liew Admin 15 years ago
hmm, if you use the script i provided, it should work. Unless there are errors in your javascript that prevent the script from working. Use the web developer tool to check if there are any errors.
Reply
Peter 15 years ago
Hi there.
I have a jQuery error on a different script I'm running at the same time, I think it may be the cause. Il try remove it later and see if it works then:)

Cheers
Reply
Zuly 15 years ago
Nice tut!
I implemented it and it was working fine, then a day ago it stopped working giving out a "try again" error.
is there any way to track down why do I get an error now?

thx in advance
Reply
nimA 15 years ago
Very clean and helpful tutorial, I've done it successfully but here's something I need to add and that is validating email before sending the email!
When you click on submit button it validates the email input even though if there is no "@" included!

I know jquery.validate can help me with it but I'm not sure how to integrate your JQuery elements with that since both have different classes to target.

Thanks for this clean tutorial, I've really enjoyed it :)
Reply
Kevin Liew Admin 15 years ago
Hi nima, yea, I didn't put email validation in this example just to show what you will need to make a ajax form. The whole intention is to make this tut as simple as possible. So, if you want to validate the email, you can use this function:

http://www.white-hat-web-design.co.uk/articles/js-validation.php

and of course, make sure you do the server side validation as well.

http://www.white-hat-web-design.co.uk/articles/js-validation.php

cheers.
Reply
nimA 15 years ago
Thanks a lot Kevin but it doesn't work with this form, I found out there can be only one alert message from one target in this case... I'll tell you what I mean:
<input type="submit" id="submit" value="Submit" />

You can't have VALUE alongside ID here, I changed the order and it didn't solve it!

When the ID is removed "Invalid Email Address " will be able to show up!
Reply
Kevin Liew Admin 15 years ago
That's weird, try change id to class instead. Make sure you change the $('#submit') to $('.submit')
Reply
nimA 15 years ago
Actually I already tried that before, won't change it...
I guess I'm going to have to combine it with "jquery.validate.js" what do you suggest me to do Kevin?
Reply
Ian Venskus 14 years ago
Hi nimA,

I was able to get email validation working for me. To do this I did the following:

Where all the variables are listed in the javascript copy and paste:

var inputVal = jQuery('input[name=email]').val();
var emailReg = /^([w-.]+@([w-]+.)+[w-]{2,4})?$/;

Then below that where all the if else statements are copy and paste:

if (!emailReg.test(inputVal)) {
email.addClass('hightlight');
return false;
} else email.removeClass('hightlight');

Then in the PHP Process File where the if's are listed in simple server side validation copy and paste:

if (!eregi("^[_a-z0-9-]+(.[_a-z0-9-]+)*@[a-z0-9-]+(.[a-z0-9-]+)*(.[a-z]{2,3})$", $email)) $errors[count($errors)] = 'Please enter a valid email address';

That should do it for you.

To see this working, please visit: http://44lizards.com/ and see the contact form at the bottom.

- Ian Venskus


Reply
Steve 14 years ago
Ian, I had to dig through your site a little to get the right information for email validation. It appears that there are some error's in what you provided above. Below is the correct version pulled from your site.

var inputVal = jQuery('input[name=email]').val();
var emailReg = /^([w-.]+@([w-]+.)+[w-]{2,4})?$/;

if (!emailReg.test(inputVal)) {
email.addClass('hightlight');
return false;
} else email.removeClass('hightlight');

And in the php process file...

if (!eregi("^[_a-z0-9-]+(.[_a-z0-9-]+)*@[a-z0-9-]+(.[a-z0-9-]+)*(.[a-z]{2,3})$", $email)) $errors[count($errors)] = 'Please enter a valid email address';

Hope this helps anyone looking for validation. It has worked for me.
Reply