Due to popular demand, here is a tutorial on how I created one of the more complicated pieces of machinery on my new site: the contact form. A lot of different techniques went into this, and I have a few people/places to thank for some of the original code that inspired my final product: primarily Design Shack for their tutorial on creating a slide-in contact form with ajax, Zachstronaut for his code on scrollable same page links (used all over my site, but most effectively on the contact link in my footer), and Yens Design for a quick how-to on creating the modal pop-up background darkening effect (surprisingly extremely easy to do with jQuery).
All you need is jQuery. No plugins are necessary for this to work, and it is only 2kb of extra code in addition to the jQuery library. This also works on all browsers, IE6 and up.
For a demo of what we are creating you need not go any further than the contact form at the top of this website, as well as the contact link in the footer, or you can go here. I’ve packaged all the files for your easy editing and applying to your own personal needs (please just don’t reuse my images. . . that would be a bit arse-like of you). I did include all of the same styling that I used on this form, to make it easier for me to write this tutorial and just in-case someone wanted to peak into how I pulled off some of the CSS.
The HTML:
<div class="container">
<div id="contactFormContainer">
<div id="contactForm">
<div class="loader"> </div>
<div class="bar"> </div>
<form name="cform" class="contactForm" action="mail.php" method="post">
<p>Talk to me about anything. If you’d like to work with me, or <br />
even if you just need a hug, I’ll get back to you shortly.</p>
<div class="input_boxes">
<p>
<label for="name">Name</label>
<span class="name-missing">Please enter your name</span><br />
<input type="text" value="" id="name" name="name" />
</p>
<p>
<label for="e-mail">E-mail</label>
<span class="email-missing">Please enter a valid e-mail</span><br />
<input type="text" value="" id="e-mail" name="email" />
</p>
<p>
<label for="message">Message</label>
<span class="message-missing">Say something!</span><br />
<textarea cols="" rows="" id="message" name="message"></textarea>
</p>
</div>
<input type="submit" onfocus="this.blur()" value="Submit Form" name="submit" class="submit" />
</form>
</div>
<div class="contact"> </div>
</div>
</div>
<div id="backgroundPopup"> </div>
I’m going to assume you know what you are doing with HTML. If you don’t, well then. . . this is NOT the post to start with! Moving on. . .
The PHP:
<?php
//declare our variables
$name = $_POST['name'];
$email = $_POST['email'];
$message = nl2br($_POST['message']);
//get todays date
$todayis = date("l, F j, Y, g:i a") ;
//set a title for the message
$subject = "Message from Your Website";
$body = "From $name, nn$message";
$headers = 'From: '.$email.'' . "rn" .
'Reply-To: '.$email.'' . "rn" .
'X-Mailer: PHP/' . phpversion();
//put your email address here
mail("youremail@yourdomain.com", $subject, $body, $headers);
?>
<!--Display a thankyou message in the callback -->
<div id="mail_response">
<h3>Thank you <?php echo $name ?>!</h3><br />
<p>I will answer your message soon as possible.</p><br />
<h5>Message sent on: </h5>
<p><?php echo $todayis ?></p>
</div>
Our mail.php breakdown:
- The comments on this more or less speak for themselves. First we are getting the variables that are passed to the file from the javascript (NOT the HTML, that’s why the ID’s of the inputs don’t match up. I had to change email to e-mail so that it didn’t conflict with the comment forms on the blog posts). Also, the function nl2br() helps to replace any new lines that the user enters onto the ‘message’ textarea with line breaks so that you get a properly formatted e-mail.
- Next, we define variables for the date, subject, body, and headers for the standard PHP mail() function.
- After the mail() function is finished executing, you will see in our javascript that we will replace the form & loader with #mail_response so that the user gets some comfy feedback that we got their message! I see way too many folks leave out user confirmation on their contact forms, and that is just plain silly. Don’t leave your users in the dark!
- I would also recommend putting some form of PHP spam protection in here as well. Another post, another time perhaps.
The CSS:
.container {
width:960px;
margin:0px auto;
position:relative;
}
/* Positions the contact form so it doesn't interfere with any other content, as well as a z-index above any other elements on the page */
#contactFormContainer {
position:absolute;
left:368px;
z-index:12;
}
/* Hides the whole contact form until needed */
#contactForm {
height:289px;width:558px;
background:#515151 url(../images/birdy.jpg) no-repeat 241px 11px;
border:1px solid #929191;
display:none;
padding:7px 12px;
color:#fff
}
/* Loading bar that will appear while the ajax magic is happening */
.bar{
display:none;
background:url(../images/ajax-loader.gif) no-repeat center;
margin-top:100px;
height:40px; width:230px;
}
/* This hides the form validation alert messages until needed */
#contactForm span {
display:none;
font-size:9px;
line-height:10px;
padding-left:6px;
color:#f5c478;
}
/* Some styling for the contact button */
#contactFormContainer .contact {
height:47px; width:211px;
background:url(../images/contact_me.png);
position:absolute;
left:368px; bottom:-44px;
cursor:pointer;
}
/* Hides the darkening layer for the Modal effect. The z-index is necessary for layering purposes, and be sure to keep the positioning/height/width the same */
#backgroundPopup{
display:none;
position:fixed;
_position:absolute;
height:100%; width:100%;
top:0; left:0;
background:#000;
z-index:11;
}
I did not include the CSS styling that I used for appearances, only what was necessary to get this functional. For everything that I used to create the form, please download the source files.
And our CSS rundown / explanation:
- .container is just used for positioning everything in the middle of the page, and the position:relative property lets us absolute position the elements inside of the div.
#contactFormContainer { position:absolute; left:368px; z-index:12; }#contactFormContainer is absolute positioning the whole contact form, this div is also necessary so that the .contact button moves with the contact form, and the z-index puts it above the darken div.- #contactForm Contains the form as well as all other content inside of it (loading bar, background, etc.) and is hidden until the .contact button is pressed.
- The spans are hidden until a user tries to submit the form without properly filling out all of the fields. You will see why each one has its own class when we take a look at the scripting.
#backgroundPopup{ display:none; position:fixed; _position:absolute; height:100%; width:100%; top:0; left:0; background:#000; z-index:11; }#backgroundPopup is placed at the bottom of the page in the HTML (it needs to be OUTSIDE of any container or else it won’t work right in IE6). This is the div that will appear and have its opacity changed when the .contact button is pressed. Make sure its z-index is above everything, but below the #contactFormContainer.
The Javascript:
PLEASE NOTE: The following javascript is a little clunky and not very well optimized. For a much cleaner version of the validation portion of this script, please visit my post The Simple, Quick, and Small jQuery HTML Form Validation Solution.
$(document).ready(function(){
//function for contact form dropdown
function contact() {
if ($("#contactForm").is(":hidden")){
$("#contactForm").slideDown("slow");
$("#backgroundPopup").css({"opacity": "0.7"});
$("#backgroundPopup").fadeIn("slow");
}
else{
$("#contactForm").slideUp("slow");
$("#backgroundPopup").fadeOut("slow");
}
}
//run contact form when any contact link is clicked
$(".contact").click(function(){contact()});
//animation for same page links #
$('a[href*=#]').each(function() {
if (location.pathname.replace(/^//,'') == this.pathname.replace(/^//,'')
&& location.hostname == this.hostname
&& this.hash.replace(/#/,'') ) {
var $targetId = $(this.hash), $targetAnchor = $('[name=' + this.hash.slice(1) +']');
var $target = $targetId.length ? $targetId : $targetAnchor.length ? $targetAnchor : false;
if ($(this.hash).length) {
$(this).click(function(event) {
var targetOffset = $(this.hash).offset().top;
var target = this.hash;
event.preventDefault();
$('html, body').animate({scrollTop: targetOffset}, 500);
return false;
});
}
}
});
//submission scripts
$('.contactForm').submit( function(){
//statements to validate the form
var filter = /^([a-zA-Z0-9_.-])+@(([a-zA-Z0-9-])+.)+([a-zA-Z0-9]{2,4})+$/;
var email = document.getElementById('e-mail');
if (!filter.test(email.value)) {
$('.email-missing').show();
} else {$('.email-missing').hide();}
if (document.cform.name.value == "") {
$('.name-missing').show();
} else {$('.name-missing').hide();}
if (document.cform.message.value == "") {
$('.message-missing').show();
} else {$('.message-missing').hide();}
if ((document.cform.name.value == "") || (!filter.test(email.value)) || (document.cform.message.value == "")){
return false;
}
if ((document.cform.name.value != "") && (filter.test(email.value)) && (document.cform.message.value != "")) {
//hide the form
$('.contactForm').hide();
//show the loading bar
$('.loader').append($('.bar'));
$('.bar').css({display:'block'});
//send the ajax request
$.post('mail.php',{name:$('#name').val(),
email:$('#e-mail').val(),
message:$('#message').val()},
//return the data
function(data){
//hide the graphic
$('.bar').css({display:'none'});
$('.loader').append(data);
});
//waits 2000, then closes the form and fades out
setTimeout('$("#backgroundPopup").fadeOut("slow"); $("#contactForm").slideUp("slow")', 2000);
//stay on the page
return false;
}
});
//only need force for IE6
$("#backgroundPopup").css({
"height": document.documentElement.clientHeight
});
});
Oh joy, lots and lots of javascript explainin’ to do:
- $(document).ready(function() {}); is the necessary jQuery function required to kick off anything that runs after the page is loaded. All our code will be placed inside of this.
function contact() { if ($("#contactForm").is(":hidden")){ $("#contactForm").slideDown("slow"); $("#backgroundPopup").css({"opacity": "0.7"}); $("#backgroundPopup").fadeIn("slow"); } else{ $("#contactForm").slideUp("slow"); $("#backgroundPopup").fadeOut("slow"); }Here we are defining the function contact that will run each time a link with the class .contact is pressed, using jQuery’s selectors:$(&quot;.contact&quot;).click(function(){contact()});This allows us to give that class to any link to execute the function that opens the contact form. What this function is doing is first determining whether the form is hidden or not, and if it is then it will slide the form down, and then change the opacity of the #backgroundPopup div as well as fade it in.$('a[href*=#]').each(function() { if (location.pathname.replace(/^//,'') == this.pathname.replace(/^//,'') && location.hostname == this.hostname && this.hash.replace(/#/,'') ) { var $targetId = $(this.hash), $targetAnchor = $('[name=' + this.hash.slice(1) +']'); var $target = $targetId.length ? $targetId : $targetAnchor.length ? $targetAnchor : false; if ($(this.hash).length) { $(this).click(function(event) { var targetOffset = $(this.hash).offset().top; var target = this.hash; event.preventDefault(); $('html, body').animate({scrollTop: targetOffset}, 500); return false; }); } } });This script grabs any anchor on the page with a same page link (e.g. #something), determines the distance between it and the destination, and then creates a scrolling transition. You can edit the speed at which it transitions by changing the ‘500′ on the line $(’html, body’).animate({scrollTop: targetOffset}, 500);.$('.contactForm').submit( function(){ var filter = /^([a-zA-Z0-9_.-])+@(([a-zA-Z0-9-])+.)+([a-zA-Z0-9]{2,4})+$/; var email = document.getElementById('e-mail'); if (!filter.test(email.value)) { $('.email-missing').show(); } else {$('.email-missing').hide();} if (document.cform.name.value == "") { $('.name-missing').show(); } else {$('.name-missing').hide();} if (document.cform.message.value == "") { $('.message-missing').show(); } else {$('.message-missing').hide();} if ((document.cform.name.value == "") || (!filter.test(email.value)) || (document.cform.message.value == "")){ return false; }I know there is a better way of doing this, but in the interest of time I quickly put this together. This is a nice long if statement that checks each required input field on the form to see if they are filled in properly or not. Doing it this way is definitely not a problem if you only have a couple of required fields, but if you have several than this will need to be rewritten. There are jQuery plugins out there that offer much more extensive validation functionality, but it was not necessary for what I wanted to accomplish with this simple form. If the field in question is not filled in correctly, then the corresponding error message (those spans we made earlier) is shown and return:false; stops the form from being submitted.if ((document.cform.name.value != "") && (filter.test(email.value)) && (document.cform.message.value != "")) { //hide the form $('.contactForm').hide(); //show the loading bar $('.loader').append($('.bar')); $('.bar').css({display:'block'}); //send the ajax request $.post('mail.php',{name:$('#name').val(), email:$('#e-mail').val(), message:$('#message').val()}, //return the data function(data){ //hide the graphic $('.bar').css({display:'none'}); $('.loader').append(data); }); //waits 2000, then closes the form and fades out setTimeout('$("#backgroundPopup").fadeOut("slow"); $("#contactForm").slideUp("slow")', 2000); //stay on the page return false; } });If all of the fields are correct, then we run the script that hides the form, shows the loading bar until the ajax variable passing to the mail.php script is complete, and then set a timer that waits ‘2000′ until it closes the whole thing. If you’d like to demo this action, please do not use the form on my website unless you want to say something to me; you can demo the form that sends a message to nowhere here.
Keep in mind, this was one of my first forays into really screwing around with jQuery/javascript using some of my own code, so I’m sure things are not perfect, and a veteran may look at some of my scripting with a bit of “wtf?” on their face. If you do get that face, please let me know of a more optimal way of doing something, and I will definitely update the code and give you credit. If you have any questions, as usual please leave them in the comments here!
DAMN shame it doesnt work properly on my website. I got it working on one page but it seems my header.tpl causes issues with it. Would have been nice, gotta say this is one of the slickest scripts I’ve seen. Good job.
Hiya,
Thanks a lot for the script. Very kind.
Do you have a version of it with the “Is ice hot or cold?” functionality added to it?
That would be great, as Im getting a load of spam.
Cheers
At this moment, I’m not going to take the time to revise the article, but it is an easy thing to accomplish. Just add the input to the form, and on the PHP end just check to see if the $_POST variable value for that input is equal to whatever you require before you run the mail function.
Yep, fair enough!
Very nice tutorial for creating useful form !
Its easy to learn even for newbie like me.. Thanks for share this …
Bunch of thanks, for posting this article. Its very nicely written so a newbie like me can understand easily. I will surely try it in one of my projects.
Thanks.
hey,this is Damian Buffy,just observed your Post on google and i must say this blog is great.may I share some of the Post found in this blog to my local people?i’m not sure and what you think?in either case,Many thanks!
Hey Awesome Script!!
I am trying to have this in one of my websites and there is a strange error every thing works fine but when i send the email i think it does not go to the mail.php file (i am assuming because the php script looks perfectly fine ) but all that happens is that loader appears as if it is trying to send but nothing happens. any suggestions ??
Thank You in advance
Hey Aniket,
Just make sure that the jQuery .post() function is pointing to mail.php correctly. If you need to do any debugging, you can always have it return some other value just to make sure everything else is working fine, use process of elimination.
Thanks for the script.
I took away the contact me image but cannot find a solution to close the dialog box if the user decides not to enter a message. Any ideas?
thanks!
Sure, best thing to do would probably take this part out
else{
$(”#contactForm”).slideUp(”slow”);
$(”#backgroundPopup”).fadeOut(”slow”);
}
And instead put those actions inside of a click event anywhere in the docready function for the darkened background that is behind the popup. That way, anywhere they click on that will close the form.
$(”#backgroundPopup”).click(function() {
$(”#contactForm”).slideUp(”slow”);
$(”#backgroundPopup”).fadeOut(”slow”);
});
Thanks very much. Works like a charm.
Hi,
I want to use ASP.Net 3.5 instead of PHP. Can anyone tell how to replace this PHP with ASP.Net.
Thanks,
Dazy.
Great stuff:) It saves my time. Big Thanks.
On your this page itself, it fails to work fine and I see 12 rotating circles with copy code symbols on sideways.
there is something wrong here on this page, however demo page works good but has no spam protection.
I am using IE 6.0
Rava
Joren Rapini please help me !!!
this form nice and good for me….
when test submit data at this form… the loader not stop.
email sent but not have anything.
can you help me ?
if you have a time. please edit contact form on my site… thanks buddy
[...] Visit Source. [...]
[...] jQuery Validation Contact Form with Modal + Slide-in Transition [...]
[...] Joren Rapini: jQuery Validation Contact Form with Modal + Slide-in Transition [...]
[...] jQuery Ajax Validation Contact Form with Modal + Slide-in Transition Due to popular demand, here is a tutorial on how I created one of the more complicated pieces of machinery on my new site: the contact form. All you need is jQuery. No plugins are necessary for this to work, and it is only 2kb of extra code in addition to the jQuery library. This also works on all browsers, IE6 and up. [...]
[...] jQuery Ajax Validation Contact Form with Modal + Slide-in Transition Due to popular demand, here is a tutorial on how I created one of the more complicated pieces of machinery on my new site: the contact form. All you need is jQuery. No plugins are necessary for this to work, and it is only 2kb of extra code in addition to the jQuery library. This also works on all browsers, IE6 and up. [...]
[...] The contact me link will darken the page and pull down a JavaScript powered box from the corner which looks very effective on a design such as this one. Joren has included instructions on how he did this on his Blog. [...]
[...] jQuery AJAX Validation Contact Form with Modal + Slide-in Transition | The Blog of Joren Rapini [...]
[...] jQuery Ajax Validation Contact Form with Modal + Slide-in Transition Due to popular demand, here is a tutorial on how I created one of the more complicated pieces of machinery on my new site: the contact form. All you need is jQuery. No plugins are necessary for this to work, and it is only 2kb of extra code in addition to the jQuery library. This also works on all browsers, IE6 and up. [...]
[...] jQuery AJAX Validation Contact Form with Modal + Slide-in Transition | The Blog of Joren Rapini [...]
[...] Uygulamanın Kodları ve Anlatım : http://jorenrapini.com/blog/css/jquery-validation-contact-form-with-modal-slide-in-transition [...]