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