Today we are going to create a nifty contact form powered by AJAX and reCAPTCHA. reCAPTCHA, now acquired by Google, was a project by Carnegie Mellon University that aims to stop bots from spamming websites. reCAPTCHA serves more than 200 million captchas everyday. It is almost impossible that you have not been challenged to type those distorted wavy words.
Did you know? reCAPTCHA words are case-insensitive. In most cases, while typing the words, we find it hard to capitalize certain characters. Well, we can just get away without capitalizing. The words entered by humans are used to digitize books. The words are from scanned old books. You can learn more here.
Update: A simple yet powerful AJAX contact form that is easy to install, is available for download. You can read about it here.

Get The Keys

We would need API keys from reCAPTCHA to show captchas. You can sign in with your Google account at reCAPTCHA and get a pair of API keys after adding a domain. (It is not necessary to own a domain, just check the the field that says "Enable this key on all domains (global key)" and the keys will work on all domains.) The first key is a public key, served via javascript and the second one is a private key to handle server-side requests. Also, download the reCAPTCHA PHP library.

Layout

Once we are ready with the keys and the library, let's begin building the form. The form we are going to create will be simple and easy to navigate. Here is how the layout is made:

First, we create an index.php file and put the following lines of code inside it.
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
<title>Contact Form With reCaptcha</title>
<style type='text/css'> 
body {
font-size: 14px;
line-height:1.3em;
text-align:center;
}
 
#wrapper {
width:600px;
margin:0 auto;
text-align:left;
padding:6px;
}

.message {
 text-align:left;
 width:100%;
 padding:15px 22px;
 display:none;
}

.loader {
 background:url("images/ajax-loader.gif") no-repeat center left;
}

.success {
 background:url("images/success.png") no-repeat center left;
}

.error {
 background:url("images/error.png") no-repeat center left;
}

.infoWrapper {
 clear:both;
 margin-top:10px;
}

.infoTitle {
 color:#808080;
 float:left;
 width:110px;
 text-align:right;
}

.infoContent {
 padding-left:130px;
 text-align: left;
}

label {
 cursor:pointer;
}

.input-text {
 border:1px solid #808080;
}

.long {
 width:450px;
}

.tall {
 height:150px;
}
</style>
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js'></script>
<script type="text/javascript" src="functions.js"></script>
</head>
<body>
<div id='wrapper'>

<h4>Contact Us</h4>
<div class='message'>

</div>

<form name='contact' id='contact'>
 <div class="infoWrapper">
  <div class="infoTitle">
   <label for='name'>Name</label>
  </div>
  <div class="infoContent">
   <input type="text" name='name' id='title' class='input-text long' />
  </div>
 </div>
 <div class="infoWrapper">
  <div class="infoTitle">
   <label for='email'>Email</label>
  </div>
  <div class="infoContent">
   <input type="text" name='email' id='title' class='input-text long' />
  </div>
 </div>
 <div class="infoWrapper">
  <div class="infoTitle">
   <label for="message">Message</label>
  </div>
  <div class="infoContent">
   <textarea name='message' id='note' class='input-text long tall'></textarea>
  </div>
 </div>
 <div class="infoWrapper">
  <div class="infoTitle">
   <label for="">Are you human?</label>
  </div>
  <div class="infoContent">
   <!-- reCAPTCHA code goes here -->
  </div>
 </div>
 <div class="infoWrapper">
  <div class="infoTitle"></div>
  <div class="infoContent">
   <input type='submit' value='Send Message'/>
  </div>
 </div>
</form>
</div>
</body>
</html>
Now, that's a lot of code that needs to be explained.
  • The first few CSS styles inside the <style> tag are pretty self-explanatory. The message class is shown at the top of the form when it is submitted. The error, success, and loader classes are to identify the kind of message shown. We will add the classnames via jQuery.
  • Each section inside the form is wrapped inside infoWrapper class. The labels are the wrapped in infoTitle class and each input field in infoContent class. The other classes (input-text, long and tall) are to prettify the form-elements.
  • We have also added jQuery javascript library and a functions.js file (we would later create).
  • We have added an empty div with message class. The text will be filled in and determined via AJAX.
  • The form, as explained earlier, is simple and minimal in its approach.
  • Note that we have commented the section where we are going to put the reCAPTCHA code.

Integrate reCAPTCHA

Now that we have the form, it's time to integrate reCAPTCHA. We add the following lines of code at the top of the index.php file:
<?php
include_once("recaptchalib.php");
define("PUB_KEY", "YOUR PUBLIC KEY HERE");
?>
recaptchalib.php is the PHP library. Of course, you need to replace "YOUR PUBLIC KEY HERE" with your actual public key. Next, we add the following codes inside the form where the reCAPTCHA codes should be (the commented section, remember?)
<?php echo recaptcha_get_html(PUB_KEY); ?>
Now, if you reload the page, reCAPTCHA words should be there. Next we are going to handle the form response via ajax.

Server Side

We create an ajax.php file and inside it, we put the following lines of code:
<?php
require_once('recaptchalib.php');
define("PRIV_KEY", "YOUR PRIVATE KEY HERE");

$name = filter_var($_POST['name']);
$message = filter_var($_POST['message']);
$email = filter_var($_POST['email']);

if(in_array('', array($name, $message, $email))) {
//one (or more) of the required fields is empty
$result = "field_error";
} else {
 $resp = recaptcha_check_answer (PRIV_KEY, $_SERVER["REMOTE_ADDR"], $_POST["recaptcha_challenge_field"], $_POST["recaptcha_response_field"]);
 if (!$resp->is_valid) {
     //Captcha was entered incorrectly
  $result = "captcha_error";
   } else {
     //Captcha was entered correctly
     $result = "success";
     //You can enter your mail functions here. It's like:
     // mail("yourmail@domain.com", "Email Subject", $message);
 }
}

echo $result;
?>
 
Let's break it down.
  • We included the recaptchalib.php library and the private key.
  • We sanitize the form data with filter_var
  • We check if any of the form data is empty with in_array. If any of them is indeed empty, we set the value of $result variable to be field_error
  • If none of the fields are empty, we check the answer for the reCAPTCHA words with recaptcha_check_answer. This function is defined inside the recaptchalib.php library.
  • The return value of recaptcha_check_answer is a PHP object. The object has a $is_valid variable value which is true if the words are typed correctly. So, we check whether the response is valid or not. If it's not valid, we set $result to captcha_error, and if it's valid $result is success. (After this point, you can mail the message to your mail address or save it to a database, as per your requirement.)
  • And finally we output $result
So, ajax.php outputs any of the three values — (1) field_error (when one or more fields is/are empty), (2) captcha_error (when typed words don't match with the captcha) and (3) success (voila).

jQuery Functions

We now create functions.js file. And inside it we put the following lines of code:
$(function(){
 $("#contact").submit(function(){
  $(".message").removeClass("success").removeClass("error").addClass("loader").html("Sending message").fadeIn("slow");
  $.ajax({
   type: "POST",
   url: "ajax.php",
   data: $(this).serialize(),
   dataType: 'text',
   success: function(msg){
    switch(msg) {
     case "field_error": // one or more fields is/are empty
      $(".message").removeClass("loader").addClass("error");
      $(".message").html("Please fill in all the required fields.");
      break;
     case "captcha_error": // captcha wasn't typed correctly
      $(".message").removeClass("loader").addClass("error");
      $(".message").html("Please type the words correctly and try again!");
      break;
     case "success": // all good
      $(".message").removeClass("loader").addClass("success");
      $(".message").html("Your message has been sent. You'll soon hear from us!");
      break;
     default: // Hmm. The default case. You never know.
      alert("Something is wrong. Please try again.");
    }
   }
  });
  Recaptcha.reload();
  return false;
 });
});
When the form is submitted, the above javascript removes success and error classes from the message section and adds the loader class to show that the message is being sent. While this is being shown to the user, an AJAX call is made that sends the form data to our ajax.php file. The response from ajax.php is then filtered with a switch. In each cases, the loader class is removed from the message section and appropriate class is added alongwith message texts. And whatever the case is, we always reload the captcha with Recaptcha.reload(). This function is provided in the javascript served via recaptcha_get_html PHP function.
If you're working with reCAPTCHA (whether on this contact form or some commenting system), you can use Recaptcha.reload() to reload the captcha without reloading the form. Helpful for form validation.
(Update: A simple yet powerful AJAX contact form that is easy to install, is available for download. You can read about it here.)
And that's it! This is just the basics of how things work. So go ahead customize and let us know in the comments. :-)

Labels: , , ,

blog comments powered by Disqus