Creating an Ajax contact form - from start to finish
Posted on Friday, June 20th, 2008In this tutorial I’ll be showing you how to create an Ajax contact form from start to finish. This includes the form HTML/CSS, the JavaScript and the PHP backend.
Obviously the form needs to work when JavaScript is disabled so we’ll have to create a functional PHP solution first, and then enhance it with AJAX. You can see an example of what we’ll achieve here.
I’m sure that most of you are proficient in basic HTML and CSS styling so I won’t spend too long on this bit.
The HTML:
The first thing to do is semantically code the form. We will be using an ordered list to contain the various form elements:
<form action="contact.php" method="post" id="contactform"> <ol> <li> <label for="name">Your Name*</label> <input id="name" name="name" class="text" /> </li> <li> <label for="email">Your Email Address*</label> <input id="email" name="email" class="text" /> </li> <li> <label for="phone">Your Phone number</label> <input id="phone" name="phone" class="text" /> </li> <li> <label for="concerning">Message concerning?</label> <input id="concerning" name="concerning" class="text" /> </li> <li> <label for="message">Your Message*</label> <textarea id="message" name="message"></textarea> </li> <li class="buttons"> <input type="submit" value="Send" id="submit" /> <input type="reset" /> </li> </ol> </form>
The CSS:
Right, now that we’ve got the markup sorted we can move on to the styling. The most usable forms, in my opinion, are the ones which retain a tabular structure since they divide each step of the form into a logical structure. So we’ll try to emulate that with some CSS:
#contactform { margin: 0; width: 500px; background: #CCCCCC; padding: 5px; } #contactform * { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; } #contactform ol { margin: 0; padding: 0; list-style: none; } #contactform li { margin: 0 0 5px 0; padding: 10px; background: #FBFAEC; } #contactform li.buttons { margin: 0; overflow: hidden; } #contactform label { margin: 0; width: 190px; display: block; float: left; padding: 5px 10px 2px 0; } #contactform input.text { width: 274px; border: 1px solid #D4D4D4; padding: 2px; margin: 0; } #contactform textarea { width: 274px; border: 1px solid #D4D4D4; padding: 2px; height: 80px; background: #FDFDF7; } #contactform li.buttons input { padding: 4px; float: right; margin: 0 0 0 5px; width: auto; }
You can see what it currently looks like here.
Now we want to write the PHP which will process the form. There are various PHP classes available for form processing (search on Google if you’re interested), but for the sake of this tutorial I will go through how to write a simple script: (Intermediate knowledge of PHP necessary)
First, create a file called contact.php and open it with your favourite text editor.
The PHP Script:
UPDATE: Tatu has put together a more graceful script (speedier and with more advanced error-checking capabilities) - You can see it here - It should work fine with the AJAX in this tutorial.[[LINK NOT WORKING ANYMORE]]
We need to check that the request for this page is always a POST request. If it isn’t then the script should not continue:
if(!$_POST) exit;
Let’s define some imortant variables:
Array of form values (name attribute):
$values = array ('name','email','phone','concerning','message');
Specify those which are required in another array:
$required = array('name','email','message');
The address the email will be sent to:
$your_email = "james@example.com";
The subject of the email:
$email_subject = "New Message";
The first line of the email:
$email_content = "new message:\n";
Now we need to loop through the form values and add them to $email_content, but the script will discontinue (exit) if any of the values specified in the $required array are empty.
for( $i = 0 ; $i < count( $values ) ; ++$i ) { for( $c = 0 ; $c < count( $required ) ; ++$c ) { if( $values[$i]==$required[$c] ) { echo $required[$x]; if( empty($_POST[$values[$i]]) ) { echo 'PLEASE FILL IN REQUIRED FIELDS'; exit; } } } $email_content .= $values[$i].': '.$_POST[$values[$i]]."\n"; }
Now we can send the email using PHP’s mail() command:
if(mail($your_email,$email_subject,$email_content)) { echo 'Message sent!'; } else { echo 'ERROR!'; }
So, the script will show either “ERROR” or “Message Sent!” dependent on whether or not the mail() command is successful. If the mail() command does not work for you then it’s likely to a be a server configuration issue (you should contact your host and have a “chat”).
So the very small PHP script is finished: (beginners: don’t forget to wrap the script in <?php & ?>
if(!$_POST) exit; $values = array ('name','email','phone','concerning','message'); $required = array('name','email','message'); $your_email = "james@example.com"; $email_subject = "New Message"; $email_content = "new message:\n"; for( $i = 0 ; $i < count( $values ) ; ++$i ) { for( $c = 0 ; $c < count( $required ) ; ++$c ) { if( $values[$i]==$required[$c] ) { echo $required[$x]; if( empty($_POST[$values[$i]]) ) { echo 'PLEASE FILL IN REQUIRED FIELDS'; exit; } } } $email_content .= $values[$i].': '.$_POST[$values[$i]]."\n"; } if(mail($your_email,$email_subject,$email_content)) { echo 'Message sent!'; } else { echo 'ERROR!'; }
It’s not perfect though. You could add some additional validation rules and to be honest the script could be a little more secure (perhaps by checking the referrer etc.) but it’ll do for now.
AJAXIFY:
Now we can add some AJAX’y coolness! Obviously we’ll be using jQuery here so you’ll need to download and link to it in your document:
<script type="text/javascript" src="jquery.js"></script>
Let’s start:
Check if document is ready for DOM manipulation:
jQuery(document).ready(function(){ // stuff here
Attach function to onsubmit event of the form:
$('#contactform').submit(function(){ // stuff here
Within the submit function: (when the form is submitted)
Assign script (action attribute) url to a variable:
var action = $(this).attr('action'); // i.e. contact.php
Add loader (animated gif) image and disable submit button:
$('#submit') .before('<img src="ajax-loader.gif" class="loader" />') .attr('disabled','disabled');
Now let’s post the data and handle the returned data: (using jQuery post method.
$.post(action, { // ALL THE DATA: name: $('#name').val(), email: $('#email').val(), phone: $('#phone').val(), concerning: $('#concerning').val(), message: $('#message').val() }, function(data){ // WHEN DATA HAS BEEN POSTED: $('#contactform #submit').attr('disabled',''); // Enable used of submit button again $('.response').remove(); // Remove any previous instances of the ".reponse" message $('#contactform').before('<span class="response">'+data+'</span>'); // Add response to document $('.response').slideDown(); // Cool effect $('#contactform img.loader').fadeOut(500,function(){$(this).remove()}); // Fade that loader img out and then remove it! if(data=='Message sent!') $('#contactform').slideUp(); // Slide up the form IF the response is positive } );
Don’t forget to return false! Otherwise the data will be submitted to contact.php normally.
return false;
Entire script:
jQuery(document).ready(function(){ $('#contactform').submit(function(){ var action = $(this).attr('action'); $('#submit') .before('<img src="ajax-loader.gif" class="loader" />') .attr('disabled','disabled'); $.post(action, { name: $('#name').val(), email: $('#email').val(), phone: $('#phone').val(), concerning: $('#concerning').val(), message: $('#message').val() }, function(data){ $('#contactform #submit').attr('disabled',''); $('.response').remove(); $('#contactform').before('<span class="response">'+data+'</span>'); $('.response').slideDown(); $('#contactform img.loader').fadeOut(500,function(){$(this).remove()}); if(data=='Message sent!') $('#contactform').slideUp(); } ); return false; }); });
SEE A FINISHED DEMO HERE!
If you have any questions about anything then feel free to leave a comment below and I’ll reply as soon as possible!
June 20th, 2008 at 5:43 pm
Hey, James. What’s up? I’m not a PHP developer, so I didn’t read over the whole tutorial. But, when reviewing the demo, I noticed that there doesn’t seem to be any validation. If I click “Send” without filling in the textboxes, it tells me “Message Sent”. It would only take a few lines of code to perform some client-side validation.
June 20th, 2008 at 6:23 pm
Jeffrey is right about validation - I really should’ve added it! … Not to worry - I just added it to the PHP backend script so the validation will work even when JS is disabled!
June 21st, 2008 at 9:38 pm
You should move the count() functions outside the for loops so it doesn’t call the function every time.
June 21st, 2008 at 10:40 pm
Better yet, now that I think about it, I would rewrite the lines as:
This keeps the $count variable in the scope of the for loop.
June 21st, 2008 at 11:38 pm
A nice tut but the PHP portion is a bit bulky, so I devised an improved version that can be found here:
http://rafb.net/p/WTkyoM41.html LINK NOT WORKING ANYMORE
There is really no need to use several nested for-loops when one foreach can handle the required fields. I also added an more intuitive error system that allows several errors to be presented to the user instead of exiting on the first error encountered - saves the user some time when they can fix all the issues at once. An easy way to validate individual fields with regular expressions is also presented.
Hope you like it and feel free to copy parts of the code if you wish.
June 21st, 2008 at 11:46 pm
Thanks Scriptdaemon and Tatu for ur great suggestions… I’m not primarily a PHP guy so I kinda assumed there was a better way of doing it.
Tatu, very nice, I’m gonna link to ur script at the top of the PHP section of the tut (as an alternative). Email validation! … nice!
June 22nd, 2008 at 8:40 pm
Sweet, the validation works now for the required fields that aren’t filled in, but the only other problem I see is that even if you enter just text in for the email address (ex: “ddd”) it still sends. Is there a way to easily evaluate the email input field to make sure a valid (or at least correctly formed) email address has been typed in?
June 22nd, 2008 at 8:54 pm
@Lindsey - Yep sure, in fact Tatu (another commenter) has put together a script with that included ( http://rafb.net/p/WTkyoM41.html - LINK NOT WORKING ANYMORE). Look on line 18:
I was going to work some advanced validation into the tut but I guess I never got round to it…
June 23rd, 2008 at 12:02 am
this is a great tutorial. i’m doing it now, and I hope I do it right.
June 23rd, 2008 at 3:58 pm
Sorry, but the script doesn’t even check if the entered email address is in fact an email address.
June 23rd, 2008 at 4:10 pm
@Wim - That’s easy enough to add though, Tatu gives an example here: http://rafb.net/p/WTkyoM41.html (LINK NOT WORKING ANYMORE)
June 23rd, 2008 at 6:41 pm
Oh, great. The link that I provided seemed to expire in 24 hours and cannot be found anymore and I don’t have the script saved. Hope you got it somewhere and are able to relink it somewhere else if you want. Thanks for noticing my message, anyhow.
June 23rd, 2008 at 8:42 pm
@Tatu - Darn! … I didn’t save it!
I remember a bit about the script (like there being a new error array - for collection of errors) but other than that I don’t remember much…
I guess there’s no way to retrieve it…
:(
June 24th, 2008 at 1:34 pm
Nice post… I like it like Milk and Company
June 24th, 2008 at 1:37 pm
Nice tutorial! I’m confused why you’re using an ordered list if you’re going for semantics. Form elements should be within a fieldset tag if that’s what your intentions were, using labels and styles to get your desired effects. Just creates a lot of overhead in your html and in your css.
June 24th, 2008 at 1:42 pm
Also, here is a function for checking the email address:
June 27th, 2008 at 2:24 pm
I’m pretty new to php & ajax. Is there a set number of fields you can use on this form? When I try to put more than 7 it won’t let me submit it. Any help on this would be greatly appreciated.
June 27th, 2008 at 9:33 pm
Other than server side validation (which was already covered) the only thing I didn’t like about the form was that it just left you hanging there after you received the “Message sent.” test. I would have changed the if statement in the ajax section into something like this:
June 27th, 2008 at 9:37 pm
I edited the form and posted it at my website. You can check out the change I made at:
http://www.firecrackerwebdesign.com/contactform.html
June 28th, 2008 at 12:46 am
Hi, everything seems to be work ok, but for some reason i receive the contact form message the sender is always “APACHE”. What can be the problem?
Thanks for this great script!
June 28th, 2008 at 7:09 am
@Zod - Did you fill the $values php array with the names of all your fields?
@Manny - You can specify various header information when using the
mail()method, for example you could have it so the email is “from” the person who filled out the form:@Rusty - Redirecting is definitely an option but may not be suitable for all apps.
@John - An ordered list originally seemed to be the best way to do it because it offered a sufficient amount of elements to style plus seemed quite a semantic way of doing it - A user has to enter data progressively through the form (usually in an order)… it makes sense to me. Nick Rigby’s solution seems to be similiar: http://www.alistapart.com/articles/prettyaccessibleforms
June 29th, 2008 at 4:43 pm
Another great tutorial!
Can I just suggest a bit of php simplification. Instead of:
use:
@John That’s a great email validating function. Using preg_match would make it slightly faster though.
July 8th, 2008 at 6:35 am
The CSS included in the file at the top doesn’t match the one in the preview, not a big deal, but if anyone didn’t notice, the response section is missing, making it not as pretty.
July 17th, 2008 at 11:42 am
Hello! I’m just wondering how to get it work with other chasets than UTF-8?
July 18th, 2008 at 10:46 am
Hi Guys,
Thanks for this great stuff.
I have 2 questions :
- I put this form in a popup, and I would like to close it when it sent. Do you know how to do that ? With Jquery in function(data) ?
- I would like to send some data in this popup(contactform.html). Actually I call it with a classic href.
Do you know how to send data into this popup and displayed in the contact form ?
Many thanks
July 31st, 2008 at 8:38 pm
Wow .. great tutz
thnx
August 16th, 2008 at 4:06 am
Great work. Anymore AJAX tutorials with php… Why use Ajax instead of Javascript though.. I’m a little confused between the two.. Has anyone checked out google’s version of javascript??
Thanks
August 21st, 2008 at 10:42 pm
is there an updated form out there?
i mean with a secure php file like email checker and so?
thx
August 26th, 2008 at 1:07 am
^ Looking for that too.
August 27th, 2008 at 5:14 pm
There is no Ajax secure form that I know of, but I am working to make one, including validations.