How to Build an Ajax-Based HTML5 Contact Form

A contact form is crucial for any website as it serves as a conduit, allowing visitors to relay their thoughts or queries directly to the webmaster. While there are numerous contact forms available online, many lack detailed explanations of their internal workings. This comprehensive tutorial will guide you through creating an advanced contact form from scratch, utilizing popular technologies like HTML5 and CSS3.

This task requires knowledge of both front-end and back-end development. We’ll explore PHP for the backend to handle email sending and jQuery to enhance the user interface. By the end of this tutorial, you will have a fully dynamic and functional contact form that is designed with future customization in mind.

Download files

Setting Up Your Development Environment

To begin, you’ll need a web server. For those on a Windows platform, WAMP is an excellent choice. Mac users can opt for a similar solution called MAMP, which is equally straightforward to install.

WAMP Server setup

These applications provide a local server environment on your computer, allowing full access to PHP. Alternatively, if you have access to your own server space or can connect to a remote server, that could be used as well. No MySQL databases are required for this project, which simplifies the setup.

After your server is ready, create a new folder to store the application. You can name it anything as it does not impact the final result. This folder structure will come into play when accessing your files through a web browser, like in the example http://localhost/ajaxcontact/contact.php

Creating Our Core Files

We will be working with two primary files. First, we need a .php file that will contain both our application logic and the front-end HTML markup. Below is a sample code snippet from our starting file.

<!DOCTYPE html>
<html xmlns:fb="https://www.facebook.com//2008/fbml" xml:lang="en" lang="en">
<head>
  <title>HTML5/CSS Ajax Contact Form with jQuery</title>
  <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
  <link href="styles.css" rel="stylesheet" type="text/css"/>
</head>

We start with a simple header section in our document. It includes a Doctype declaration for HTML5, and various HTML/XML elements that, while not strictly necessary, help ensure consistent rendering across different browsers. Additionally, providing more information generally enhances compatibility and functionality.

Further in the document, just before the closing head tag, we include two crucial lines. The first line adds a jQuery script from the Google Code Repository, essential for handling dynamic page functionalities. Right below that, we link a basic CSS file that applies styles to our webpage.

In the document body, we feature several container divisions that encapsulate the main contact form. This form includes input fields for the user’s name, e-mail address, and personal message. The HTML structure is straightforward and should be easily understood by an intermediate developer.

<!-- @begin contact -->
<div id="contact" class="section">
  <div class="container content">

  <?php if(isset($emailSent) && $emailSent == true) { ?>
    <p class="info">Your email was sent. Huzzah!</p>
  <?php } else { ?>

Here, we have straightforward PHP conditional code embedded within a few page containers. It checks whether a variable named $emailSent is set and true, displaying a success message if the conditions are met.

Details of the Form HTML Structure

The else statement will be executed on the initial page load when no data has been sent. This section includes a collection of form elements and a submit button.

<div id="contact-form">
  <?php if(isset($hasError) || isset($captchaError)) { ?>
    <p class="alert">Error submitting the form</p>
  <?php } ?>

  <form id="contact-us" action="contact.php" method="post">
    <div class="formblock">
      <label class="screen-reader-text">Name</label>
      <input type="text" name="contactName" id="contactName" value="<?php if(isset($_POST['contactName'])) echo $_POST['contactName'];?>" class="txt requiredField" placeholder="Name:"/>

      <?php if($nameError != '') { ?>
        <br/><span class="error"><?php echo $nameError;?></span> 
      <?php } ?>
    </div>

    <div class="formblock">
      <label class="screen-reader-text">Email</label>
      <input type="text" name="email" id="email" value="<?php if(isset($_POST['email'])) echo $_POST['email'];?>" class="txt requiredField email" placeholder="Email:"/>

      <?php if($emailError != '') { ?>
        <br/><span class="error"><?php echo $emailError;?></span>
      <?php } ?>
    </div>

    <div class="formblock">
      <label class="screen-reader-text">Message</label>
      <textarea name="comments" id="commentsText" class="txtarea requiredField" placeholder="Message:"><?php if(isset($_POST['comments'])) { if(function_exists('stripslashes')) { echo stripslashes($_POST['comments']); } else { echo $_POST['comments']; } } ?></textarea>

      <?php if($commentError != '') { ?>
        <br/><span class="error"><?php echo $commentError;?></span> 
      <?php } ?>
    </div>

    <button name="submit" type="submit" class="subbutton">Send us Mail!</button>
    <input type="hidden" name="submitted" id="submitted" value="true"/>
  </form>
</div>

<?php } ?>
</div>
</div><!-- End #contact -->

Notice the additional conditional block immediately following the form’s start. It checks for errors using variables like $hasError and displays an error message if any are found. This method acts as a fallback when JavaScript is disabled, as the dynamic error handling won’t function.

Further down, we handle individual PHP error checks for each input field. These checks ensure that even if the form is submitted with incomplete data, the filled fields will retain their values, enhancing the user experience.

Following the form, there are several jQuery functions implemented. We’ll discuss these first since they are the default handling method on page load. However, if JavaScript is not supported by the browser, the PHP code will serve as a reliable fallback.

Introduction to jQuery

The best way to start discussing jQuery is to dive straight into an example. I will break down individual blocks of code line-by-line so you can understand what the script checks for.

If you find yourself getting lost, simply review the project code files. All code blocks are pre-written and well-documented on the jQuery website. We begin our code in a standard manner:

<script type="text/javascript">
  <!--//--><![CDATA[//><!--
  $(document).ready(function() {
    $('form#contact-us').submit(function() {

The initial lines check for specific events. After using CDATA comments to shield the script from older browsers, we start by checking if the document is ready for manipulation – a fundamental jQuery practice.

We then look for submissions of a form with the ID “contact-us“, which triggers another function that handles either displaying error messages or executing a slideUp() effect upon successful submission.

$('form#contact-us .error').remove();
var hasError = false;
$('.requiredField').each(function() {
  if($.trim($(this).val()) == '') {
    var labelText = $(this).prev('label').text();
    $(this).parent().append('<span class="error">You forgot to enter your '+labelText+'.</span>');
    $(this).addClass('inputError');
    hasError = true;
  } else if($(this).hasClass('email')) {
    var emailReg = /^([\w-\.]+@([\w-]+\.)+[\w-]{2,4})?$/;
    if(!emailReg.test($.trim($(this).val()))) {
      var labelText = $(this).prev('label').text();
      $(this).parent().append('<span class="error">Sorry! You\'ve entered an invalid '+labelText+'.</span>');
      $(this).addClass('inputError');
      hasError = true;
    }
  }
});

We begin by removing any existing error messages to ensure we start fresh. Next, we target elements with the class “requiredField“, which include the name, e-mail, and message fields.

jQuery checks each field’s value and alerts the user if it is empty, or if the e-mail does not match the regular expression pattern, indicating an invalid input.

If no errors are found, we proceed to submit the form via jQuery’s post() method. Assuming no server-side errors, a slideUp() animation is used to hide the form and show a “success!” message.

if(!hasError) {
  var formInput = $(this).serialize();
  $.post($(this).attr('action'), formInput, function(data){
    $('form#contact-us').slideUp("fast", function() { 
      $(this).before('<p class="tick"><strong>Thanks!</strong> Your email has been delivered. Huzzah!</p>');
    });
  });
}

return false; 
});
});
//-->!]]>
</script>

The use of callbacks in jQuery is also demonstrated here. A callback is a smaller function called in response to data received from another function. For instance, when our jQuery.post() successfully sends an email, it triggers a function that initiates the sliding animation. This approach allows us to keep the callback inline for simplicity in this tutorial.

Navigating Through Our PHP Logic

The final key component to discuss is the logic behind our PHP backend. This system is responsible for invoking a mail function and sending out the message. You can find all the code for this at the top of our main .php file, before any HTML is output.

Additionally, a few internal styles help enhance the page’s appearance. There isn’t anything particularly new here, so we won’t delve into details. The styles.css file included in the project uses basic CSS3 techniques.

<?php 
// If the form is submitted
if(isset($_POST['submitted'])) {

We begin by checking if the form was submitted, using the POST variable “submitted” which is a hidden input field placed at the end of our form. This check helps avoid unnecessary server resource use if no data has been submitted.

Following this, we have three separate if/else statements checking if each input field is filled out. Here’s an example of the e-mail verification logic:

// Need valid email
if(trim($_POST['email']) === '') {
  $emailError = 'Forgot to enter in your e-mail address.';
  $hasError = true;
} else if (!preg_match("/^[[:alnum:]][a-z0-9_.-]*@[a-z0-9.-]+\.[a-z]{2,4}$/i", trim($_POST['email']))) {
  $emailError = 'You entered an invalid email address.';
  $hasError = true;
} else {
  $email = trim($_POST['email']);
}

PHP trims all whitespace from the email value and verifies it against a Regular Expression (Regex) to ensure it matches a typical email pattern.

You don’t need to be an expert in preg_match() to use this script. It’s a powerful function used to enforce specific data types and patterns, like ensuring an email includes valid characters and a domain.

Once all checks are passed with no errors, it’s time to send our message! Here’s how we configure the email parameters and headers:

// Upon no failure errors, let's email now!
if(!isset($hasError)) {
  $emailTo = 'youremailhere@googlemail.com';
  $subject = 'Submitted message from '.$name;
  $sendCopy = trim($_POST['sendCopy']);
  $body = "Name: $name \n\nEmail: $email \n\nComments: $comments";
  $headers = 'From: ' .' <'.$emailTo.'>' . "\r\n" . 'Reply-To: ' . $email;

  mail($emailTo, $subject, $body, $headers);
  
  // Set our boolean completion value to TRUE
  $emailSent = true;
}

If you’ve ever wondered how the script identifies your email address to send messages to, here’s where you specify it in the $emailTo variable.

The $body of the email uses the \n delimiter to format the message with lines for the sender’s name, email address, and their message content. This format is simple yet effective for reading the message clearly.

Conclusion

This concludes our tutorial on creating an advanced contact form. If you want to style your elements similar to the provided example, you can refer to the styles.css file included in the project. However, the structure is straightforward enough that you could easily design your own aesthetic.

Feel free to download the source code to examine the project more closely. It’s beneficial to follow a tutorial, but accessing the source directly can be invaluable. A brief stylesheet is also included to facilitate easy customizations. Thanks for following along!

WebsiteFacebookTwitterInstagramPinterestLinkedInGoogle+YoutubeRedditDribbbleBehanceGithubCodePenWhatsappEmail