Get our posts emailed to you with our monthly newsletter, subscribe here.

Modal windows have become a popular asset for web & mobile developers. iPhone and iPad applications have such a limited screen real estate that it’s useful to bring in additional menus floating on top of the view. This concept also translates well into webpage interfaces where you can hide smaller, minute details.

In this tutorial I’ll demonstrate how we can build a minimalist modal contact form. I’ll be using jQuery along with the fancybox plugin to manage dynamic content. The open source code libraries make scripting so much easier. And we can implement a small Ajax call which submits the form data via PHP on the server end.

Live Demo PreviewDownload Source Code

Starting the Webpage

For the demo I’m using a simple white background and some link text, nothing overly complicated. But in the document header we will need to include some very specific files.

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script><script type="text/javascript" src="fancybox/jquery.fancybox.js?v=2.0.6"></script>

First you should download the latest Fancybox from their website and unzip to your workspace. I’ve taken the entire “source” folder and copied it over with the name “fancybox”. Now we can reference the plugin’s CSS/JS files quickly without hosting on a web server.

The core page HTML is very straightforward but it’s important to explain some bits. I’ve got the contact form wrapped in a div and hidden on the page using CSS. When you click the href link it opens a modal box with the exact inline content.

<div id="wrapper">
Send us feedback from the modal window.

<a class="modalbox" href="#inline">click to open</a></div>

<!-- hidden inline form -->
<div id="inline">
<h2>Send us a Message</h2>
<form id="contact" action="#" method="post" name="contact"><label for="email">Your E-mail</label>
	<input id="email" class="txt" type="email" name="email" />

	<label for="msg">Enter a Message</label>
	<textarea id="msg" class="txtarea" name="msg"></textarea>

	<button id="send">Send E-mail</button></form></div>

Styling the Form

Our CSS document is mostly full of resets and positioning. The only interesting styles relate to the form itself, for :hover and :active states.

.txt {
	display: inline-block;
	color: #676767;
	width: 420px;
	font-family: Arial, Tahoma, sans-serif;
	margin-bottom: 10px;
	border: 1px dotted #ccc;
	padding: 5px 9px;
	font-size: 1.2em;
	line-height: 1.4em;
}

.txtarea {
	display: block;
	resize: none;
	color: #676767;
	font-family: Arial, Tahoma, sans-serif;
	margin-bottom: 10px;
	width: 500px;
	height: 150px;
	border: 1px dotted #ccc;
	padding: 5px 9px;
	font-size: 1.2em;
	line-height: 1.4em;
}

.txt:focus,
.txtarea:focus {
	border-style: solid;
	border-color: #bababa;
	color: #444;
}

input.error,
textarea.error {
	border-color: #973d3d;
	border-style: solid;
	background: #f0bebe;
	color: #a35959;
}

input.error:focus,
textarea.error:focus {
	border-color: #973d3d;
	color: #a35959;
}

I setup a subclass .error which we can add onto the input fields using jQuery. This will recolor the text, border, and background to differing shades of red. After the user has successfully entered valid data the field will revert back to normal.

#send {
	color: #dee5f0;
	display: block;
	cursor: pointer;
	padding: 5px 11px;
	font-size: 1.2em;
	border: solid 1px #224983;
	border-radius: 5px;
	background: #1e4c99;
		background: -webkit-gradient(linear, left top, left bottom, from(#2f52b7), to(#0e3a7d));
			background: -moz-linear-gradient(top, #2f52b7, #0e3a7d);
				background: -webkit-linear-gradient(top, #2f52b7, #0e3a7d);
					background: -o-linear-gradient(top, #2f52b7, #0e3a7d);
						background: -ms-linear-gradient(top, #2f52b7, #0e3a7d);
							background: linear-gradient(top, #2f52b7, #0e3a7d);
								filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#2f52b7', endColorstr='#0e3a7d');
}

#send:hover {
	background: #183d80;
		background: -webkit-gradient(linear, left top, left bottom, from(#284f9d), to(#0c2b6b));
			background: -moz-linear-gradient(top,  #284f9d, #0c2b6b);
				background: -webkit-linear-gradient(top, #284f9d, #0c2b6b);
					background: -o-linear-gradient(top, #284f9d, #0c2b6b);
						background: -ms-linear-gradient(top, #284f9d, #0c2b6b);
							background: linear-gradient(top, #284f9d, #0c2b6b);
								filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#284f9d', endColorstr='#0c2b6b');
}

#send:active {
	color: #8c9dc0;
		background: -webkit-gradient(linear, left top, left bottom, from(#0e387d), to(#2f55b7));
			background: -moz-linear-gradient(top,  #0e387d,  #2f55b7);
				background: -webkit-linear-gradient(top, #0e387d, #2f55b7);
					background: -o-linear-gradient(top, #0e387d, #2f55b7);
						background: -ms-linear-gradient(top, #0e387d, #2f55b7);
							background: linear-gradient(top, #0e387d, #2f55b7);
								filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0e387d', endColorstr='#2f55b7');
}

The button CSS is also really interesting since we’re using some CSS3 gradients. Per hover and active states I’ve recreated the linear colors to reverse, and this gives the impression of being “lowered” into the page. But now that we have covered the markup let’s jump into scripting.

jQuery with Fancybox

Right from the document.ready() call we need to setup the fancybox default variable. This will target all selectors for the fancybox effect when clicked – in our scenario this means any element with the class .modalbox.

$(document).ready(function() {
	$(".modalbox").fancybox();
	$("#contact").submit(function() { return false; });

The second line of code is disabling the default contact form submission. This way we can handle the click event ourselves and pass the data through Ajax. After the user submits the form we need to get the current value of our two fields(e-mail and message). We also want to check if the e-mail address is valid and if the message is more than a few letters long.

$("#send").on("click", function(){
	var emailval  = $("#email").val();
	var msgval    = $("#msg").val();
	var msglen    = msgval.length;
	var mailvalid = validateEmail(emailval);

	if(mailvalid == false) {
		$("#email").addClass("error");
	}
	else if(mailvalid == true){
		$("#email").removeClass("error");
	}

	if(msglen < 4) {
		$("#msg").addClass("error");
	}
	else if(msglen >= 4){
		$("#msg").removeClass("error");
	}

This can be done quickly using some if/else logic statements. The form won’t be submitted until the e-mail looks valid and the message is longer than 4 letters.

Sending the Ajax Request

Now for the 2nd part of this onclick event handler we need to send the form data into PHP. This is how the contact form is actually submitted and we will receive the e-mail in our inbox.

if(mailvalid == true && msglen >= 4) {
		// if both validate we attempt to send the e-mail
		// first we hide the submit btn so the user doesnt click twice
		$("#send").replaceWith("<em>sending...</em>");

		$.ajax({
			type: 'POST',
			url: 'sendmessage.php',
			data: $("#contact").serialize(),
			success: function(data) {
				if(data == "true") {
					$("#contact").fadeOut("fast", function(){
						$(this).before("<strong>Success! Your feedback has been sent, thanks :)</strong>");
						setTimeout("$.fancybox.close()", 1000);
					});
				}
			}
        });
	}
});

If both the fields validate then we replace the submit button using some text. This gives the user acknowledgement that both fields are valid and we are trying to send the message.

Now the ajax request can be confusing if you’ve never seen this syntax before. We basically need to specify header information including the datatype(POST or GET), script name, and form variables. jQuery has a handy method .serialize() for just this purpose.

If we get a good response from the server then we hide the contact form and display a success message. I’m using the setTimeout() method to close the fancybox one second after the form is hidden. The JS code to do this looks like $.fancybox.close().

Sending Mail in PHP

Thankfully you don’t need to be a PHP programmer to fully understand how this works. We send the user input variables using jQuery into a new file sendmessage.php. Within PHP we setup the initial message and then try sending it, returning a value of “true” or “false” back to jQuery.

$sendto   = "noreply@mail.com";
	$usermail = $_POST['email'];
	$content  = nl2br($_POST['msg']);

	$subject  = "New Feedback Message";
	$headers  = "From: " . strip_tags($usermail) . "\r\n";
	$headers .= "Reply-To: ". strip_tags($usermail) . "\r\n";
	$headers .= "MIME-Version: 1.0\r\n";
	$headers .= "Content-Type: text/html;charset=utf-8 \r\n";

	$msg  = "";
	$msg .= "<h2 style="font-weight: bold; border-bottom: 1px dotted #ccc;">New User Feedback</h2>\r\n";
	$msg .= "<strong>Sent by:</strong> ".$usermail."\r\n";
	$msg .= "<strong>Message:</strong> ".$content."\r\n";
	$msg .= "";

You shouldn’t be expected to understand all of this, and it shouldn’t interfere with the script. But the first variable $sendto should be changed to whichever e-mail you want receiving these messages. Additionally you may want to change the $subject var which sets the e-mail’s subject line.

Live Demo PreviewDownload Source Code

Final Thoughts

This type of miniature contact form works well on newer website launches. Startups who need to handle quick feedback and suggestions from their users will thrive with this scale of speedy information transfer. Check out the demo source code above and see if you can implement a similar modal box on your own web projects.

Posted by Jake Rocheleau

Jake is a freelance writer, designer, and illustrator. He currently writes articles on user experience design and web development techniques. You can check out his work on Dribbble and follow his tweets @jakerocheleau.

21 Comments

  1. Hello :)
    Nice script ! But how can me use this form opening from site meniu, from CONTACT !! Thank you, best regards !

  2. Really nice script.

    Does anybody have a simple way to reset the form after it has been sent though?

    If I click the contact form link again after submitting I get the success message pop up again, whereas I would like the blank form to show again (i.e. back to its original state).

    Also when I refresh the page and click the link the old data shows in the fields.

    Have tried a few things but with no success so any help appreciated. Thanks.

    1. hi redsnapper,
      …did you get an answer?
      I’m having the same issue.

    2. I had the same issue and I resolved it with the callback method afterClose (see more onhttp://fancyapps.com/fancybox/). I moved the whole logic in a separate function, then just called that function twice: on first load and the next ones. Here is the changed code in fancybox.js, hope it helps :)

      $(document).ready(function() {
      var html = $("#inline").html();
      $(".modalbox").fancybox({
      afterClose : function() {
      $("#inline").html(html);
      feedback();
      }
      });
      var feedback = function(){
      $("#contact").submit(function() {return false; });
      $("#send").on("click", function(){
      var emailval = $("#email").val();
      var msgval = $("#msg").val();
      var msglen = msgval.length;
      var mailvalid = validateEmail(emailval);

      if(mailvalid == false) {
      $("#email").addClass("error");
      }
      else if(mailvalid == true){
      $("#email").removeClass("error");
      }

      if(msglen = 4){
      $("#msg").removeClass("error");
      }

      if(mailvalid == true && msglen >= 4) {
      // if both validate we attempt to send the e-mail
      // first we hide the submit btn so the user doesnt click twice
      $("#send").replaceWith("sending...");

      $.ajax({
      type: 'POST',
      url: 'sendmessage.php',
      data: $("#contact").serialize(),
      success: function(data) {
      if(data == "true") {
      $("#contact").fadeOut("fast", function(){
      $(this).before("Success! Your feedback has been sent, thanks :)");
      setTimeout("$.fancybox.close()", 1000);
      });
      }
      }
      });
      }
      });
      }
      feedback();
      });

    3. Hi Lidiya, thanks for your reply and you’ve solved half the issue very neatly. Still have this problem though:

      When I refresh the page and click the link the old data shows in the fields.

      Any ideas for that one would be greatly appreciated

    4. Well, try adding those lines in the afterClose callback function before feedback() call:
      $(“.txt”).html();
      $(“.txtarea”).html();
      In that way, with jQuery, you just empty the text fields, and then call the fancybox again :).

  3. thanks for this tutorial! just one comment, you forgot to put this line of code in your php:
    mail($sendto, $subject, $msg, $headers);

    other than that, it is flawless.

  4. Is it possible to make the box disappear and then have a button showing, and if you click the button the popup will appear again ?

  5. when i click on send mail button it is replace with Sending .. . but box dose not close by itself neither i am receive any mail even after changing send to: in .php file , i’m running my site from localhost (WAMP). do i need to change some setting or code ???

    1. Using localhost you can not send email unless you configure SMTP in php.ini

  6. I love this tutorial, and it looks great. Only issue is I want to have the user input their phone number instead of their email address. I tried using input type “tel”, and updating the sendmessage.php to call that instead but it’s not working?

  7. Hello People,

    Can je help me please,
    I have use this greet script but i want it more than ones in one page. but as i copiet the

    Insturen

    Je Voor en Achternaam

    Verzenden

    2 times then works the validate option no more…..

    Can jou please help me ?

    Greezz
    ps: sorry for my bad english im dutch…..;-)
    Dennis

  8. OK, I have done next field at this form :)
    But now I have a question – how to change:
    $sendto = “noreply@mail.com”;
    to get info about admin mail from WP settings?
    When I use:
    bloginfo(‘admin_email’)
    it doesn’t work.

    1. Almost, Use: $admin_email = get_option('admin_email');

    2. Thanks, but it’s not working. Why?
      I also coudn’t use my option from my “theme options”.
      Any where I put:
      get_option(‘MyTheme_email’)
      it is working. But in your example I could use anything else, I could use only “noreply@mail.com”;
      I am waiting for yours reply :)

  9. Hi,
    It’s very good. But I have problem, when I want to add “name” field.
    Would you like to help me and show me how to do this?
    Thanks.

  10. you make a beautiful and useful jquery popup and i learn many things due to your tutorial.

  11. Hi! Useful and easy to follow tutorial with cool result :) thank you )

  12. Thanks for the breakdown, I’ve been looking for ways to improve the contact form on one of my sites.

  13. Yup this is fantastic and a very helpful tutorial. Kudos for sharing and publishing with so much detail.

  14. Hi,
    Great tuto, tks.
    Question though, why is it appropriate to use fancybox? I thought it was not necessary for that kind of modal pop up boxes?
    Many thanks,

Comments are closed.