Create an AJAX/jQuery/PHP Contact Form

The CSS

The CSS can be whatever you want. For this tutorial we’ve used some simple icons and some clean, white and grey colours. I recommend using a CSS reset file (a good example is Eric Meyers’ CSS reset, which can be easily edited for your personal requirements).

The most important aspect of the css file is that #mask, #contact, .success and .error need to have their display set to display:none. This makes sure that these div’s don’t show up when the page is loaded.

The width and height of the #mask div are set to 100% so that, when displayed, it fills the whole screen. It has a z-index of 9000 to make sure that it appears on top of most of the page, but below the #contact div, which has a z-index of 9999.

body {
color:#222;
font-size:16px;
font-family:helvetica, verdana, arial, san-serif;
line-height:1.5em;
}

a {
color:#06F;
text-decoration:underline;
}

p {
padding:10px 0;
}

#container {
width:900px;
margin:20px auto;
}

/*contact form*/
#mask {
background-color:#000;
display:none;
height:100%;
left:0;
position:absolute;
top:0;
width:100%;
z-index:9000;
}

#contact {
background-color:#fff;
display:none;
left:50%;
margin-left:-300px;
position:absolute;
top:90px;
width:600px;
z-index:9999;
border-radius:10px;
-moz-border-radius:10px;
-webkit-border-radius:10px;
padding:20px;
}

#close {
background:url(../images/close.png) no-repeat right;
cursor:pointer;
font-family:arial, sans-serif;
font-size:20px;
font-weight:700;
line-height:24px;
text-decoration:underline;
text-align:right;
padding:5px 30px 5px 5px;
}

#contact_header {
background:url(../images/envelope.png) no-repeat left;
font-family:arial, sans-serif;
font-size:30px;
font-weight:700;
line-height:50px;
padding:5px 5px 10px 60px;
}

/* form components */
input,textarea {
border:1px solid silver;
background-color:#fff;
color:#404040;
font-size:10px;
font-family:Verdana, Arial, sans-serif;
text-transform:uppercase;
border-radius:5px;
-moz-border-radius:5px;
-webkit-border-radius:5px;
margin:10px 0;
padding:10px;
}

input:hover[type=text],input:focus[type=text],textarea:hover,textarea:focus {
background-color:#E0E0E0;
border:1px solid #000;
}

input[type=text],textarea {
width:300px;
}

#submit {
border:none;
width:87px;
height:41px;
background-image:url(../images/submit.png);
}

#submit:hover {
cursor:pointer;
}

/* alert messages */
.success,.error {
color:#000;
display:none;
font-size:15px;
font-weight:700;
border-radius:4px;
-moz-border-radius:4px;
-webkit-border-radius:4px;
padding:5px 10px 5px 10px;
margin-bottom: 10px;
}

.success {
background-color:#9F6;
border:1px solid #0F0;
}

.error {
background-color:#F66;
border:1px solid red;
}

Pages: 1 2 3 4

This entry was posted on Friday, April 30th, 2010 at 10:38 and is filed under Tutorials. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

Simon Patterson is a freelance web designer and developer based in South Wales, UK who loves to fuse beauty and function. Follow Simon on Twitter or visit his Blog

About the author Published by Simon

55 Responses »

  1. Poor usability, no client and server side validation… but design is great 🙂

  2. Thanks g23,

    We will look in to this and will update the code asap 😉

  3. Its a beginner tutorial therefore validation could be ignored but resetting the textfields after onFocus (User typed text in it already) is a usability issue! 🙂

  4. Thanks for the tutorial. Perhaps, rather than

    $('input#submit').click(function() {

    you could use

    $('#contactForm').submit(function() {

    which would handle using the keyboard to submit the form?

  5. Yes, huge usability and validation problems. Say hello to spammers.

  6. Might want to check the PHP too, handling emails is a hard task and was poorly done here. I can inject headers into your code with your poor security.

  7. The code of this tutorial has been updated, thanks to Cody. Re-download the source files please.

  8. Good article.

    I have a suggestion when you receive data, that is using stripslashes is not always right. It’s right only when magic quote is enabled (by default, but some host disables it). You need to check it.

    And for validation, you can simply use strip_tags for removing all HTML tags to make sure user doesn’t submit harmful code.

  9. I agree with david above.
    The form process should be executed on form submit rather than on the click of the submit button.

    This is because it will skip all the lovely ajax if the form is submitted with the ‘enter’ button.

  10. hi,
    It nice web design tips, coding is ok but validation is not done..
    keep going on..

  11. Excellent tutorial thanks for sharing…

  12. @Ruchi

    You need to look closer, I added validation on the client side.

  13. Thank’s for this tut…
    Great 🙂

  14. it messes up my design …

  15. It seems that the form is not working properly. I have tested it on my site and the live demo and I get the same “invalid username” result. Please respond asap.

    • Mistake is here: if(!username_regex.test(name)) { , Just replace on this: if(!username_regex.test(username)) {

      Regards

  16. Very basic. You can improve this tutorial by adding extra security like CAPTCHA and kicking server side validation automatically when JS is disabled. I’ve not checked the code in all the browsers but looks good.

  17. Here is a good one,
    Ajax’d Form with Fancy Email
    http://bit.ly/arltdj

  18. If your going to post a tutorial like this, don’t you think testing it would be a good idea? I also get �invalid username� result.

  19. Having worked through this tutorial, I then realised it had errors, finally I checked your demo and that has errors too. Would be logical to test these before you post the tutorial as I now have wasted a couple of hours on this.

  20. Nice script I love the effects on it, but (without the intention of being cocky or something similar) I follow the tutorial that you post, and it didn’t work in the validation part.

    I check your code and modify it a little bit (sorry for do that). I don’t know if you include this on pourpose or if you only miss that part.

    var username = $(‘#name’).val(),

    //Test Username
    if(!username_regex.test(name)) {
    $(‘#contact_header’).after(‘Invalid usernameentered!’);
    error_count += 1;
    }

    you declare the variable as username, but you are using a variable name to do the comparison, also I think that you only need to compare if the username is empty or not instead of using a regular expresion to do it, you won’t be able to know if any user name is to weird 🙂

    Thanks again for you code, it was an amazing code and easy to understand. I’m just beginning to work with jQuery.

  21. Attractive form however no matter what modifications I made to var username or name, I couldn’t get it to validate a name. Too bad.

  22. My appreciation for sharing!! 🙂

    If there is a way that the “invalid username” can be fixed…
    I would highly appreciate it!

    I love the form…and am using it for another site..
    however…i’m a little stuck on the error…
    and i would love to maintain & use the contact form…

    I look forward to hearing back with a fabulous fix soon :o)

    Light & love,
    Aline [ArtWave]

  23. I have checked through the code and design. I think the design is great. However the validation is not working at all! If you could fix this, then it would be perfect!

    Regards, Mwanaume

  24. Great looking form, nicely laid out etc but after a couple of hours of tweaking I can’t get the name field to validate either. Shame this hasn’t yet been addressed as out of a bunch of css, ajax contact forms I’ve been stumbling upon, this one has been one of the tidiest.

  25. Hello !!!
    Plz fix the code !!!

  26. code clean :

    $(function() {

    // load the modal window
    $(‘a.modal’).click(function(){

    // scroll to top
    $(‘html, body’).animate({scrollTop:0}, ‘fast’);

    // before showing the modal window, reset the form incase of previous use.
    $(‘.success, .error’).hide();
    $(‘form#contactForm’).show();

    // Reset all the default values in the form fields
    $(‘#name’).val(‘Votre nom et pr�nom’);
    $(‘#email’).val(‘Votre adresse mail’);
    $(‘#comment’).val(‘Votre demande/message…’);
    $(‘#ville’).val(‘Votre ville’);
    $(‘#telephone’).val(‘Votre num�ro’);

    //show the mask and contact divs
    $(‘#mask’).show().fadeTo(”, 0.7);
    $(‘div#contact’).fadeIn();

    // stop the modal link from doing its default action
    return false;
    });

    // close the modal window is close div or mask div are clicked.
    $(‘div#close, div#mask’).click(function() {
    $(‘div#contact, div#mask’).stop().fadeOut(‘slow’);

    });

    $(‘#contactForm input’).focus(function() {
    // $(this).val(‘ ‘); <– celui l�, il �tait traitre !
    $(this).val('');
    });

    $('#contactForm textarea').focus(function() {
    $(this).val('');
    });

    // when the Submit button is clicked…
    $('input#submit').click(function() {
    $('.error').hide().remove();

    //Inputed Strings

    var username = $('#name').val();
    var email = $('#email').val();
    var ville = $('#ville').val();
    var telephone = $('#telephone').val();
    var comment = $('#comment').val();

    //Error Count
    // var error_count;
    var error_count = 0;

    //Regex Strings
    // var username_regex = /^[a-z0-9_-]{3,16}$/, //Original
    var username_regex = new RegExp('^[ a-z�����������������0-9_-]{3,32}$','i'); // une erreur ici : la ligne �tait finie par une virgule, au lieu d'un point virgule… J'ai ajout� les majuscules et espaces au masque de contr�le, et allong� la limite, car le formulaire indique Nom & Pr�nom, 16 caract�res, �a peut �tre trop court…
    // email_regex = /^([a-z0-9_\.-]+)@([a-z0-9\.-]+)\.([\ba-z\.]{2,6})$/; //Original
    var email_regex = new RegExp('^([a-z0-9_\.-]+)@([a-z0-9\.-]+)\.([\ba-z\.]{2,6})$', 'i'); //Original

    //Test Username
    if(!username_regex.test(username)) {
    $('#contact_header').after('Nom invalide !’ + username);
    error_count += 1;
    }

    //Test Email
    if(!email_regex.test(email)) {
    $(‘#contact_header’).after(‘Erreur de mail !’ + email);
    error_count += 1;
    }

    //Blank Comment?
    if(comment == ”) {
    $(‘#contact_header’).after(‘Aucun commentaire �cris !’);
    error_count += 1;
    }

    //No Errors?
    if(error_count === 0) {
    $.ajax({
    type: “post”,
    url: “send.php”,
    // data: “$name=” + name + “&email=” + email + “$ville” + ville + “$telephone” + telephone + “&comment=” + comment, //ORIGINAL
    data: “name=” + name + “&email=” + email + “&ville=” + ville + “&telephone=” + telephone + “&comment=” + comment,
    error: function(return_val) {
    //DEVMODE alert(‘error : ‘+return_val);
    $(‘.error’).hide();
    $(‘#sendError’).slideDown(‘slow’);
    },
    success: function (return_val) {
    //DEVMODE alert(‘success : ‘+return_val);
    $(‘.error’).hide();
    $(‘.success’).slideDown(‘slow’);
    $(‘form#contactForm’).fadeOut(‘slow’);
    }

    });
    }

    else {
    $(‘.error’).show();
    }

    return false;
    });

    });

  27. Is this tutorial working now? I noticed quite a few comments above stating that it did not work. I was just wondering if it has been corrected.

    By the way, some of the comments were a bit rude in light of the fact that this gentleman took the time to offer his FREE code. Lighten up people.

    Damn.

  28. Still has validation error “Invalid Username Entered”…

  29. A friend as also having issues with the username field so I took a quick look and have a couple things that could be added to fix the issue. I appeared that when the username is compared in the regex it has a leading space so “MyName” is what you would expect but it is actually ” MyName”, this could be fixed by adding a username.trim() before using the regex test. Also it appeared as if the form is capitalizing everything the user types, and the regex is not setup to match on upper case characters. This can be addressed either by first lower casing the username variable before doing the comparison, by adding in a A-Z to the regex so it will match on those characters, and/or by adding modifiers on the end of the regex /gi on the end of username_regex for a global case insensitive compare.

    like this: /[A-Za-z0-9_-]{3,16}/gi

    I’d also suggest a few other improvements for your script, first the error messages could be more descriptive than just the one given, it would be nice if the user knew why the username was invalid such as “usernames can’t have spaces”, “username must be 3 or more characters”, “username must be less than 17 characters”, “username must be all lower case”. You could implement this is length comparisons or other regex tests, if you don’t want to go to that extent you could just make the error message more descriptive to include the possible causes for the errors.

    There also are some performance optimizations you could make in your javascript as well. Things like the username and username_regex could be defined outside of the event handlers and still accessed through the closure scope so they only have to be defined once. You could also consider namespacing your code and caching your jquery selectors.

    Anyway, since I helped by buddy look at the username issue I thought I’d share a possible fix and some feedback. Hope this help, thanks for sharing your code.

  30. I still can’t get this to work even with the clean js posted by romain. It doesn’t even open the modal window… So I’m still stuck with the username error, even though I’ve fixed the var name error, and tried swap over the regex for the one romain used…

    Any suggestions?

  31. Hi, i have used this form and added, but it is not working. INVALID NAME. can you clear this thing. THanks

  32. Hi There.

    Is if(error_count === 0) correct with 3 “===”
    Is there a later version of the module.

  33. Thanks for the turtorial.
    However the validation is still not working.
    Somebody here who got it working?

  34. I confirm that this is not working…. User name issue…