Creating an Ajax Form
May 12, 2009 | Posted in Javascript, PHP
When creating forms that need to be validated against a user's input, you can either validate on the client-side (Javascript), or the server-side (PHP in this case).
But if you want to use Javascript, then someone with Javascript turned off could easily submit the form and bypass all validation.
That's where AJAX comes in. You do all the validation on the server-side, but return the results back to the user with Javascript and no page refreshes. It's really the best of both worlds. Plus it degrades good enough if someone has Javascript disabled.
Download
View Demo
Step 1 - HTML
Let's start with the HTML layout of the form. It'll just be a simple contact form with three fields.
<div id="form">
<form id="contact" method="post" action="">
<label for="name">Your Name:</label>
<input type="text" name="name" id="name" class="input" />
<label for="email">Your Email:</label>
<input type="text" name="email" id="email" class="input" />
<label for="message">Message:</label>
<textarea name="message" id="message" rows="4" cols="40" class="input"></textarea>
<input type="hidden" name="contact" value="1" />
<p><button type="submit">Submit!</button></p>
</form>
</div>
We wrapped the form in a div for use later with the Javascript.
Step 2 - The PHP
When the form is submitted, the PHP will go validate all the fields and return a result back to the Javascript to let it know if everything went ok. If there are errors it returns a JSON encoded string with the errors.
<?php
if ( ! empty($_POST['contact']))
{
$valid = array
(
'name' => array('/^[\w\d\._\-]+$/iD', 'Your name isn\'t filled out correctly.'),
'email' => array('/^[-_a-z0-9\'+*$^&%=~!?{}]++(?:\.[-_a-z0-9\'+*$^&%=~!?{}]+)*+@(?:(?![-.])[-a-z0-9.]+(?<![-.])\.[a-z]{2,6}|\d{1,3}(?:\.\d{1,3}){3})(?::\d++)?$/iD', 'You must provide a valid email.'),
'message' => array('/(.+){10,}/', 'You can\'t send a blank message.'),
);
$errors = array();
foreach ($valid as $field => $data)
{
$regex = $data[0];
$message = $data[1];
$input = trim($_POST[$field]);
if (empty($input) OR ! preg_match($regex, $input))
{
$errors += array($field => $message);
}
}
$result = empty($errors) ? 'success' : 'errors';
echo json_encode(array
(
'result' => $result,
'errors' => $errors,
));
exit;
}
?>
Alright, so first we check for the hidden field contact to make sure the form was submitted.
If it was, then we set up our validation array. So each key of the array corresponds to the form field we want to validate, and it holds another array with the Regular Expression to validate against, and also the error message to show if it fails validation.
So then we loop through the validation array and make sure each required field isn't empty, and also check it against the Regex. If it fails the Regex, then we add it to the $errors array.
The errors array is just an associative array (key => value) with the field name and the error message.
Then, we check if there are any errors, and set our $result variable to the appropriate value. We do this so the Javascript can figure out what to do with the JSON data, depending on whether the validation passed or failed.
Finally, the result and errors are echoed with the json_encode() function that Javascript will read in. And don't forget that last exit, because without it the rest of the HTML page would render and screw up our JSON output.
Step 3 - Javascript
Now we finally get to the javascript. I like the jQuery library, so we'll be using that. So let's first include the latest version of jQuery from google:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
Now here's the javascript. The comments should help explain what's going on.
/**
* Just a simple function to enable / disable our submit button
* It lets the user know we're working on the request, and something is actually happening.
*/
(function() {
$.fn.toggleButton = function() {
var $this = $(this),
disabled = $this.attr('disabled');
( ! disabled) ? $this.html('Submitting...').attr('disabled', 'disabled')
: $this.html('Send!').attr('disabled', '');
return this;
}
})();
// Shortcut to $(document).ready()
$(function() {
// Attach function to the 'submit' event of the form
$('#contact').submit(function() {
var self = $(this), // Caches the $(this) object for speed improvements
post = self.serialize(); // Amazing function that gathers all the form fields data
// and makes it usable for the PHP
// Disable the submit button
self.find('button').toggleButton();
// Send our Ajax Request with the serialized form data
$.post('index.php', post, function(data) {
// Since we returned a Json encoded string, we need to eval it to work correctly
var data = eval('(' + data + ')');
// If everything validated and went ok
if (data.result == 'success') {
// Fade out the form and add success message
$('#contact').fadeOut(function() {
$(this).remove();
$('<div class="message success"><h4>Thanks for your email!</h4></div>')
.hide()
.appendTo($('#form'))
.fadeIn();
});
}
else {
// Hide any errors from previous submits
$('span.error').remove();
$(':input.error').removeClass('error');
// Re-enable the submit button
$('#contact').find('button').toggleButton();
// Loop through the errors, and add class and message to each field
$.each(data.errors, function(field, message) {
$('#' + field).addClass('error').after('<span class="error">' + message + '</span>');
});
}
});
// Don't let the form re-load the page as would normally happen
return false;
});
});
Conclusion
So there ya go! We now have a working Ajax form.
Hopefully the code helped you out and gave you some new ideas on accomplishing this common task.









Hy, anywhere a zip file?
Just added a download link at the top!
Hi. This form looks great!
Exactly what I need. Simple, in one file, with validation.
However I can't get it to work. :/
I have tried 2 different servers and it doesn't work.
Submit button changes to Submitting... and there is no further action...
I have uploaded it so you can preview http://www.swioklo.com/ajax_form.php
if you could give me any idea on what can be wrong it would be very much appreciated.
thanks a lot
Piotr
@Piotr Swioklo: I would recommend installing Firebug for Firefox for future javascript debugging.
The problem here though was my fault, this line:
$.post('index.php', post, function(data) {Should be changed to this:
$.post('ajax_form.php', post, function(data) {Here do I specify the recieving email?
Thanks
I left out the e-mail part of this tutorial. Not sure why, guess I just thought it was out of the scope of this tutorial. You will need to add in the actual code to send the email. http://php.net/mail
Hi! Seems a clean and nice solution, but can't make it work. Even if I try to test the downloaded example on localhost or live server (on steadfast) after submitting the empty form, all it does is the button's text changes to "submitting". What could be the problem? Thanks Corey!
Hi again! Just figured out the mistake. Everything works great. Just was wondering how do add a field that is not required, but just to be checked for regular expressions? Thanks in advance!
Hi! I found this form the coolest one in the collection. Just what I was looking for. Works as expected. I added a php mail script to the form action attribute. It did not send mail. I then had to comment line# 63 of your JavaScript : return false;
Then the mail goes ok, but page is redirected to mail script and hangs. Where am I going wrong? Can you please help..?
Hello,
Hope you can help, I wanted to know where do I put the PHP send email code. I have very limited amount of PHP knowledge.
Any help is much appreciated
my email is qakbar@hotmail.co.uk
Thank you
ASDFGH
ASDFEGHJYKWERETYUKLO
Hi!
It's just great script. But it doesn't accept Russian letters (not validating them).
I think it's somewhere in this code, but I can't get what to change there..
'name' => array('/^[\w\d\._\-]+$/iD', 'Your name isn\'t filled out correctly.')
And one more little problem. I want to redirect after mail sent. I tried this code, but it doesn't work :(
if (data.result == 'success') {
$.ajax({
url: "http://mysite.com/thx"
});
What I am doing wrong?
I've been trying for 2 days to find a form that does this and doesn't mess with my already styled contact form.
And now, you forget the most important part of the form??
;)
My search continues...
@Gina: Hmmm, not sure what you mean. What did I leave out?
Corey, now you are playing dumb to Gina. You are losing a lot of loyalty. I'm moving on as well.
@Eric: Hahaha. Are you a bot?
Need help!
Everything is cool!
Exept one thing, every time that I press on send button it sends mail, even if no fields filled. What should I do to stop mailing?
What I have to insert before mail tag in php part of file?
Someting like if succes - mail, if not don't mail! But how to write it, help plz!
Why don't you just tell us how to make the mail part of the darned form!!
Calm down man. You don't get what you want by yelling. And the mail part isn't in the scope of this tutorial. Did I title this post "Creating an Ajax Form and Sending an Email"? Nope.
There is an error. When you press on send button it send's email in any case. even if all fields not filled
Pretty stupid to not include the mail part in this tutorial. You're acting like an asshole in response to people asking for help.
Hi, i really like this contact form, however like others i cant send mail. Can you tell me exactly what code to add and where. Thanks