Talk to me about anything. If you’d like to work with me, or
even if you just need a hug, I’ll get back to you shortly.

Please enter your name

Please enter a valid e-mail

It's cold!

Say something!

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. 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">&nbsp;</div>
      <div class="bar">&nbsp;</div>
      <form name="cform" class="contactForm" action="mail.php" method="post">
        <p>Talk to me about anything. If you&rsquo;d like to work with me, or <br />
          even if you just need a hug, I&rsquo;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">&nbsp;</div>
  </div>
</div>
<div id="backgroundPopup">&nbsp;</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:

    $(&amp;quot;.contact&amp;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!

Advertisement: Let me give you a postcards printing site that will let you print just about any kind of cards. Whether you’re printing personal cards for your loved ones or friends or die cut business cards for use at work, you’ll all get them on here. Visit us today!

363 Comments
  1. Hi.. Well.. I finally got it working using my Mac with Safari.. only to find that it will not work on IE or Firefox.. And with Opera, it opens but does not send correctly.. ..

    Shame.. Looks awesome.. Love it.. I am not a programmer so it was hard to get it to this point… I was so happy when it worked for me… but it will not work for anyone else so not good..

    Destiny..

    January 22, 2013 at 4:55 am
    Reply

  2. Kimberly Smith

    christian work from home, work at home employment, legit work at home
    Prof Mark will assist Christians as they seek to work from home. Affiliate web training. Legit work from home jobs!
    http://www.profmarksays.com/
    real work at home jobs, legit work at home jobs

    March 27, 2013 at 6:29 pm
    Reply

  3. Anthony Turner

    big idea mastermind, bim
    http://bimtopteam.com
    This 100% Automated System Brought In $710,000 In 28 Days. Recently we tested a brand new marketing idea, basically doing the polar opposite of what everybody else is doing online. Results were mind blowing to say the least: First 28 days = over $710,000 net profit. First 2.5 months = almost $1.2 Million! Right now this pulls $12,485 per DAY on average.
    Vick Strizheus, big idea mastermind Vick Strizheus

    March 27, 2013 at 7:42 pm
    Reply

  4. Christina Smith

    Samsung UN50EH5300
    With this Samsung Smart TV, Smart Content provides new ways to locate your favorite entertainment.
    http://www.smarttv-review.com/samsung-un50eh5300-50-inch-smart-tv/

    March 28, 2013 at 2:35 am
    Reply

  5. Earl Adams

    shoulder bag, satchel, Hera Business, mandarina duck hera business kelly, shoulder bag, Mandarina Duck, hera business bag
    http://www.citypurse.com/mandarina-duck-hera-business-shoulder-bag-in-navy-blue/
    Mandarina Duck Hera Business shoulder bag in navy blue
    by Lisa in $450-500, Leather Bags, Mandarina Duck, Satchels, Shoulder bags
    My Overall Rating:
    An exquisite medium-sized kelly bag removable handle and shoulder strap, ideal for the working girl or for anyone looking for an elegant satchel which wouldn’t look out of place in any metropolis. Available in black, brown, red and pictured here in navy blue, this bag doesn’t come cheap, but is long on style and well worth forking out for.
    mandarina duck business bag, hera business shoulder bag, navy blue, navy blue, Hera Business, satchel

    April 5, 2013 at 10:14 pm
    Reply

  6. Michael Miller

    kitchen remodeling fairfax va, kitchen remodelers fairfax va, fairfax kitchen remodeling
    “Fairfax Kitchen Remodeling: Quality Design Build has been providing quality Kitchen Remodeling in Fairfax, VA for 24 years. We are a Class (A) full-service remodeling contractor. custom kitchen cabinets, hardwood flooring, custom tile work, granite counter tops and custom wood finishing. We offer granite and appliances at wholesale cost. Mention coupon code PDQ1 to save. Call: (571) 292-1025

    http://www.youtube.com/watch?v=4kVNGwZNMq0
    kitchen and bath remodeling fairfax va, kitchen remodeling fairfax virginia

    April 12, 2013 at 4:08 pm
    Reply

  7. Scott Garcia

    relieve back pain, back pain acupuncture, cure back pain, chronic lower back pain, back pain therapy, help back pain
    http://www.relievebackpaininfo.com
    Articles, Videos and Tips To Relieve Chronic Low Back Pain!
    back pain problems, back pain remedies, treatment low back pain, exercises for low back pain, low back pain treatment, how to relieve back pain

    April 20, 2013 at 2:30 pm
    Reply

  8. Sharon Johnson

    diamond, pattern, daily, video
    Learn more about Forex Technical Analysis Techniques
    http://www.automatedforextradingnews.com/forex-education-video-showing-dxy-daily-diamond-chart-pattern/
    showing, chart, education, forex

    April 20, 2013 at 4:47 pm
    Reply

  9. Spot on with this write-up, I actually feel this amazing site needs a lot more attention.
    I’ll probably be returning to see more, thanks for the info!

    April 21, 2013 at 3:57 am
    Reply

  10. Mary Miller

    Forex, GrowthBot
    http://forexgrowthbotreview.com/
    I Made Almost 1,000% Profit in a Matter of Months.
    Almost 1,000% gain, 4% daily, 121% monthly. Scroll down to learn how you can use Forex Growth Bot to automate your income… trading currency.
    GrowthBot, Forex

    April 25, 2013 at 10:02 am
    Reply

  11. Harold Bailey

    bathroom remodeling norman ok, remodeling contractors norman oklahoma, norman oklahoma home remodel
    Westside Construction and Remodeling has been providing quality home Remodeling in the Norman, Ok area for 40 years. We are a family owned & operated. We provide remodeling services for both residential & commercial properties including: Kitchen remodeling, Bathroom remodeling, Room Additions, Decks, Patios, Porches and Garages. One Year Guarantee on labor and your Satisfaction is 100% guaranteed. Call us for your free remodeling estimate: (405) 360-4445. Mention Coupon Code: PDQ1 for extra savings
    http://www.youtube.com/watch?v=dCn8Dkx7v6s
    remodeling norman ok, home remodeling norman ok

    April 26, 2013 at 11:16 am
    Reply

  12. Sean Miller

    evansville heating and air conditioning, evansville heating and air, air conditioning evansville indiana
    Evansville Heating and Air Conditioning contractor offers 24/7 emergency service, free estimates. Honest & reliable family owned for over 30 years. Fully licensed, insured & bonded. Call: Byers Heating and Air Conditioning: (812) 965-6366
    http://www.youtube.com/watch?v=Mrd8Ms20SAs
    heating air conditioning evansville, evansville heating air conditioning

    April 26, 2013 at 11:54 am
    Reply

  13. Paul Ross

    Gen F20 Plus Ingredients
    http://besthghsupplement.org/genf20plusingredients/
    Many people have found that GenF20 Plus has been able to help them feel young and to get back the lean body that they used to have. The question then is, what are the ingredients found in this Gen F20 Plus?

    April 27, 2013 at 7:46 pm
    Reply

  14. Ruth Smith

    stone patios northern virginia, northern virginia concrete patio, northern virginia patio installation
    https://www.youtube.com/watch?v=F20RPIBII-Y
    Northern Virginia Patio Contractors with over 23 years of experience Custom patios for residential and commercial properties. Concrete patio, patio deck, patio pavers, stone patios, stamped concrete patio or paver brick patios. 10% discount - satisfaction guaranteed. Call us today for your free estimate. (703) 475-8795
    patio pavers northern virginia, northern virginia patio

    May 16, 2013 at 12:23 pm
    Reply

  15. [...] How to Create a Stunning and Smooth Popup Using jQuery [...]

    April 26, 2013 at 1:49 am
    Reply

  16. [...] This is the page with the tutorial for all the code http://jorenrapini.com/blog/css/jquery-validation-contact-form-with-modal-slide-in-transition [...]

    May 4, 2013 at 4:04 pm
    Reply

  17. [...] Download this item [...]

    May 9, 2013 at 9:59 pm
    Reply

Leave a Reply