Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
June 7, 2011 07:38 pm GMT

Build a Neat HTML5 Powered Contact Form

Advertise here

In this tutorial, we are going to learn how to create a swanky HTML5 AJAX powered contact form. The form will use some of the new HTML5 input elements and attributes, and will be validated using the browser’s built-in form validation.

We will use jQuery and Modernizr to help out with the older browsers, and PHP on the server side to validate the input.


Step 1: Getting Started

To begin, we need to setup our directory and files. To get started, I highly recommend the HTML5 boilerplate. This is a really good starting point for any HTML5 project and will save you a great deal of time. For this tutorial I chose ‘BOILERPLATE CUSTOM’.

HTML5 Boilerplate

For more information on the HTML5 boilerplate check out this guide on Nettuts+.

Once downloaded and unpacked, delete everything but index.html and the css and js folders. I also added a folder called img and a PHP file called process.php. We will use the img folder for storing image assets for our form, and process.php to handle all the server-side logic for the contact form. Here is what my directory structure looks like now:

Directory Structure

That’s all we need to get started! The HTML5 boilerplate includes an awesome CSS reset with sensible defaults and includes all the JS libraries (jQuery & Modernizr) we are going to be using today. All our JS files and CSS files have been hooked up in the index file. Now, it’s time to move on to the markup.


Step 2: The Form

Open index.html, and remove everything within the #container element. We’ll put our contact form inside this div:

<div id="contact-form" class="clearfix">    <h1>Get In Touch!</h1>    <h2>Fill out our super swanky HTML5 contact form below to get in touch with us! Please provide as much information as possible for us to help you with your enquiry :) </h2>    <ul id="errors" class="">        <li id="info">There were some problems with your form submission:</li>    </ul>    <p id="success">Thanks for your message! We will get back to you ASAP!</p>    <form method="post" action="process.php">        <label for="name">Name: <span class="required">*</span></label>        <input type="text" id="name" name="name" value="" placeholder="John Doe" required="required" autofocus="autofocus" />        <label for="email">Email Address: <span class="required">*</span></label>        <input type="email" id="email" name="email" value="" placeholder="[email protected]" required="required" />        <label for="telephone">Telephone: </label>        <input type="tel" id="telephone" name="telephone" value="" />        <label for="enquiry">Enquiry: </label>        <select id="enquiry" name="enquiry">            <option value="general">General</option>            <option value="sales">Sales</option>            <option value="support">Support</option>        </select>        <label for="message">Message: <span class="required">*</span></label>        <textarea id="message" name="message" placeholder="Your message must be greater than 20 charcters" required="required" data-minlength="20"></textarea>        <span id="loading"></span>        <input type="submit" value="Holla!" id="submit-button" />        <p id="req-field-desc"><span class="required">*</span> indicates a required field</p>    </form></div>

This is all the HTML we will need for our form. Let’s look at each individual section:

ul#errors and p#success will be holders for our error and success messages. We will hide these by default with CSS, and display them with either JavaScript or PHP once the form has been submitted. For the name input, our only requirement is that it has been filled in.

In HTML5, we do this by adding the 'required' attribute. This will force the browser to check that this field has something in it before it allows the form to be submitted. The email field is similar, but as well as being required, we actually want to make sure it is an email address that was entered. To do this, we specify this input’s type as email, which is new in HTML5. Although telephone is not a required field, we are using the tel HTML5 input type for this.

Enquiry is a standard select element, and message is a typical textarea — nothing new here. To the textarea, we will set the required attribute to make sure the user enters some text.

In HTML5, there is a new attribute for textareas called maxlength. Yep, you guessed it, this lets us set a maximum number of characters we can write in the textarea. For some daft reason, the powers that be who made the HTML5 spec did not think we would need a minlength attribute (like we do now) and there is no attribute for this. So as a makeshift minlength attribute, we are going to use another new HTML5 attribute called a custom data attribute. This is basically any attribute name prefixed with the word ‘data-’. In our case we have appropriately chosen data-minlength. This lets us essentially create our own attributes.

Another thing worth noticing is that we are setting an attribute called placeholder on all of the input elements (except telephone) and the textarea. This is a new HTML5 input attribute. When the form is first displayed, the placeholder text will appear in the input, normally in a different font color. Then, when you focus the input, the placeholder text disappears. If you blur out without filling the field in, the placeholder text is put back in. This is a pretty cool effect, and can provide the user with a bit more information on what they need to do. Previously, this would have had to be done with JavaScript.

The final thing to notice is that the name input has an HTML5 attribute, called autofocus. When the page is first loaded, this input element is given focus immediately without the user having to do anything. This is also good for prompting the user to do something.

That’s all the HTML5-ness we are going to incorporate into our markup. For more detailed information on these new attributes and inputs checkout some of these links:


Step 3: Styling the Form

Here is our form, looking a little worse for wear…

Unstyled Form

It does not look too good at the moment, and it isn’t really doing our shiny new HTML5 goodness any justice, so let’s add some CSS. Open the style.css file. The file already contains some resets and defaults that will help us make our form x-browser compatible. Scroll down and look for a comment saying:

/*    // ========================================== \\   ||                                              ||   ||               Your styles !                  ||   ||                                              ||    \\ ========================================== //*/

Directly after it, paste in the following CSS:

#contact-form {    background-color:#F2F7F9;    width:465px;    padding:20px;    margin: 50px auto;    border: 6px solid #8FB5C1;    -moz-border-radius:15px;    -webkit-border-radius:15px;    border-radius:15px;    position:relative;}#contact-form h1 {    font-size:42px;}#contact-form h2 {    margin-bottom:15px;    font-style:italic;    font-weight:normal;}#contact-form input,#contact-form select,#contact-form textarea,#contact-form label {    font-size:15px;    margin-bottom:2px;}#contact-form input,#contact-form select,#contact-form textarea {    width:450px;    border: 1px solid #CEE1E8;    margin-bottom:20px;    padding:4px;}#contact-form input:focus,#contact-form select:focus,#contact-form textarea:focus {    border: 1px solid #AFCDD8;    background-color: #EBF2F4;}#contact-form textarea {    height:150px;    resize: none;}#contact-form label {    display:block;}#contact-form .required {    font-weight:bold;    color:#F00;}#contact-form #submit-button {    width: 100px;    background-color:#333;    color:#FFF;    border:none;    display:block;    float:right;    margin-bottom:0px;    margin-right:6px;    background-color:#8FB5C1;    -moz-border-radius:8px;}#contact-form #submit-button:hover {    background-color: #A6CFDD;}#contact-form #submit-button:active {    position:relative;    top:1px;}#contact-form #loading {    width:32px;    height:32px;    background-image:url(../img/loading.gif);    display:block;    position:absolute;    right:130px;    bottom:16px;    display:none;}#errors {    border:solid 1px #E58E8E;    padding:10px;    margin:25px 0px;    display:block;    width:437px;    -webkit-border-radius:8px;    -moz-border-radius:8px;    border-radius:8px;    background:#FFE6E6 url(../img/cancel_48.png) no-repeat 405px center;    display:none;}#errors li {    padding:2px;    list-style:none;}#errors li:before {    content: ' - ';}#errors #info {    font-weight:bold;}#errors #info:before {    content: '';}#success {    border:solid 1px #83D186;    padding:25px 10px;    margin:25px 0px;    display:block;    width:437px;    -webkit-border-radius:8px;    -moz-border-radius:8px;    border-radius:8px;    background:#D3EDD3 url(../img/accepted_48.png) no-repeat 405px center;    font-weight:bold;    display:none;}#errors.visible, #success.visible {    display:block;}#req-field-desc {    font-style:italic;}/* Remove box shadow firefox, chrome and opera put around required fields. It looks rubbish. */input:required, textarea:required {    -moz-box-shadow:none;    -webkit-box-shadow:none;    -o-box-shadow:none;    box-shadow:none;}/* Normalize placeholder styles *//* chrome, safari */::-webkit-input-placeholder {    color:#CCC;    font-style:italic;}/* mozilla */input:-moz-placeholder, textarea:-moz-placeholder {    color:#CCC;    font-style:italic;}/* ie (faux placeholder) */input.placeholder-text, textarea.placeholder-text  {    color:#CCC;    font-style:italic;}

If you save and reload, your page should now look like so:

Styled Form

Now that looks better! The CSS is pretty standard, but I will go over a few things that are not so obvious:

#errors li:before {    content: ' - ';}

This will put a dash next to our error validation messages. It’s basically replacing the bullet point in the list, I just think this looks better.

#contact-form #submit-button:active {    position:relative;    top:1px;}

This will give us a nice ‘push-down’ effect when the submit button is active.

input:required, textarea:required {    -moz-box-shadow:none;    -webkit-box-shadow:none;    -o-box-shadow:none;    box-shadow:none;}

All browsers (except IE) by default put a red box shadow around required elements. This looks a bit over the top in my opinion, so I am removing it. I have already indicated that the field is required by putting a red asterisk in the label.

Stupid looking required inputs
/* chrome, safari */::-webkit-input-placeholder {    color:#CCC;    font-style:italic;}/* mozilla */input:-moz-placeholder, textarea:-moz-placeholder {    color:#CCC;    font-style:italic;}/* ie (faux placeholder) */input.placeholder-text, textarea.placeholder-text  {    color:#CCC;    font-style:italic;}

This normalizes the appearance of the placeholder text on inputs and textareas. Here we are making it a light grey and italicizing it. This will give us consistency across all browsers except Opera, which does not support the styling of placeholders. IE just does not support the placeholder attribute. Fullstop. We will be using JavaScript to polyfill this. You can read more about styling HTML5 forms with CSS(2.1 + 3) here.

You will notice in the CSS that there are a few references to images. If you do not have these, simply download the source files for this tutorial and copy them over.

We’re done with the markup, and it’s looking pretty sweet. We’re going to create a PHP fallback in case the user’s browser does not support the new form input attributes (IE), or if the user has JavaScript disabled. We are going to write some JavaScript later to polyfill the features the browser lacks. But incase the user does not have a nice shiny new browser or JavaScript enabled, we still need to validate the form submission. We will do this serverside with PHP. We are also going to use it to email us the results of a valid form.


Step 4: Preparing For The Server Side Validation

Let’s dive straight in. Open up process.php and paste in the following:

<?phpif( isset($_POST) ){    //form validation vars    $formok = true;    $errors = array();    //sumbission data    $ipaddress = $_SERVER['REMOTE_ADDR'];    $date = date('d/m/Y');    $time = date('H:i:s');    //form data    $name = $_POST['name'];    $email = $_POST['email'];    $telephone = $_POST['telephone'];    $enquiry = $_POST['enquiry'];    $message = $_POST['message'];    //form validation to go here....}

What we are saying here is: only execute this following code when the request method is POST. By default, if a form is posted to a PHP script, the form’s input values are stored in a super global array called $_POST. If nothing is posted, $_POST will not be an array, the if statement will equate to false and our code will not be run.

Once we have established that this is a POST request, we can start our form processing logic. The first thing we need to do is set two variables:

  • $formok: A boolean value we can check to see if the form was valid or not at the end of the script.
  • $errors: An array that we will use to store all of the problems with the form, as we are validating it.

After that, we set some general form submission data:

  • $ipaddress: User’s IP address which can be useful for blacklisting spam, cross referencing analytics data etc.
  • $date: The date the form was submitted. We use the date function to generate the date in UK format.
  • $time: The time the form was submitted. We use the date function to generate the time.

We could combine the date and time if we wanted:

$datetime = date('d/m/Y H:i:s');

I like to keep them separate so I can use them for other things, if required. The final set of variables we are setting are the values of the submitted form fields . We are accessing the $_POST array by passing in the form field name as the key to retrieve the data for each variable.


Step 5: Validating the $_POST Data

We are going to check each variable individually now to make sure their value is valid. If it’s not, we’ll set the $formok variable to false, and store an error message in the $errors array. We will start with the name field first.

//validate name is not emptyif(empty($name)){    $formok = false;    $errors[] = "You have not entered a name";}

Here, we are just making sure that $name actually has a value. If it does not, it means the user did not enter a name. We are using the empty() function to check for this. The [] after $errors is a shortcut to array_push (which is used to add an item to the end of an array). Next we will validate the email address:

//validate email address is not emptyif(empty($email)){    $formok = false;    $errors[] = "You have not entered an email address";//validate email address is valid}elseif(!filter_var($email, FILTER_VALIDATE_EMAIL)){    $formok = false;    $errors[] = "You have not entered a valid email address";}

We are going to check to see if a valid email address was actually entered. For this task, we are going to use the filter_var() function. Finally, we’ll need to validate the message.

//validate message is not emptyif(empty($message)){    $formok = false;    $errors[] = "You have not entered a message";}//validate message is greater than 20 charcterselseif(strlen($message) < 20){    $formok = false;    $errors[] = "Your message must be greater than 20 characters";}

Yet again, we are going to check to see if a message was entered. If something was entered, we want to make sure it’s greater than 20 characters. For this, we are going to use the strlen() function.

The telephone field and the enquiry field are not required fields, so no need to validate these. You could, if you wanted, but for the purpose of this tutorial I’m not.


Step 6: What to do Next…

Once we have validated our form results, we need to decide whether to send the user an email containing the form results or not. We kept track of the validity of the form using the $formok variable. If it is still equal to true, we want to submit the form results, otherwise we don’t.

This is the logic we are going to use to send the message (paste this in after we have done our validation):

//send email if all is okif($formok){    $headers = "From: [email protected]" . "\r\n";    $headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";    $emailbody = "<p>You have recieved a new message from the enquiries form on your website.</p>                  <p><strong>Name: </strong> {$name} </p>                  <p><strong>Email Address: </strong> {$email} </p>                  <p><strong>Telephone: </strong> {$telephone} </p>                  <p><strong>Enquiry: </strong> {$enquiry} </p>                  <p><strong>Message: </strong> {$message} </p>                  <p>This message was sent from the IP Address: {$ipaddress} on {$date} at {$time}</p>";    mail("[email protected]","New Enquiry",$emailbody,$headers);}

To send the message, we are going to be using the mail() function. We will need to pass this function four parameters: to, subject, message and headers.

  • to: This will be the email address that you want to send the form details to.
  • subject: This will be the email’s subject.
  • message: This will be the email’s content. We are storing this in the variable $emailbody. This is a HTML string containing the results of our form. Where you see the curly braces with our variable names in them, these will be changed into the variables value when this script is run. This is called variable substitution. This sort of substitution only works if the string is encapsulated in DOUBLE quotes, not SINGLE.
  • headers: This is used to pass additional information to the email client so it knows how to interpet the email. We are storing our headers in the $headers variable and supplying extra information on who the email is from, and what type of content it contains.

Note: Remember to change the from email address in the headers and the to email address in the mail function.

This should produce a nice email like so:

Email Screenshot

If you are on a Windows server, you may need to put this line of code in (before you declare the $headers variable) to get the mail function to work:

ini_set("sendmail_from","[email protected]");

Whether the user’s form submission was valid or not, we want to return them back to the form. If the form was valid and the message was sent, we need to provide the user with the success message. If it’s not valid, we want to display the error messages stored in the $errors array as well as populate the form fields with the data that was originally sent. We will store some variables we have been using in this script in an array and send them along with the redirect back to the form.

//what we need to return back to our form$returndata = array(    'posted_form_data' => array(        'name' => $name,        'email' => $email,        'telephone' => $telephone,        'enquiry' => $enquiry,        'message' => $message    ),    'form_ok' => $formok,    'errors' => $errors);

We will be storing our data in an associative array. This array has three members:

  • posted_form_data: This will be an array containing the form data that was posted to the script.
  • form_ok: We will store the $formok variable in this, and this variable will be checked back on the form page to update the user with the appropriate message.
  • errors: We will store the $errors variable in this. This variable will be used if the $formok variable is equal to false.

The final thing for us to do is to redirect the user back to the form page, along with our $returndata array. Once we are redirected back to the form page, we will lose our $returndata variable; so, to make this data persistant, we will temporarily store it in the session.

Another thing we need to bear in mind is, ultimately, if the user’s browser has JavaScript enabled, we want to submit the form via AJAX. That will mean we will want our AJAX request to be posted to the same place as the form submission when the JavaScript is disabled. Because the form would have already been validated on the client-side, it will pass through all the server-side validation, and the details will be emailed to us. If the form is not valid, it will never be submitted (as the browser validation / JavaScript will prevent it). This means that, with the AJAX request, there is no reason for us to redirect or set any session variables. In the final part of this script, we will check to see if the current request to process.php was an AJAX request or not, and if it was, set our session variables and redirect.

//if this is not an ajax requestif(empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) !== 'xmlhttprequest'){    //set session variables    session_start();    $_SESSION['cf_returndata'] = $returndata;    //redirect back to form    header('location: ' . $_SERVER['HTTP_REFERER']);}

To check if this was an AJAX request, we search for the variable, $_SERVER['HTTP_X_REQUESTED_WITH'] . Like the the super global $_POST array, there is also one called $_SERVER. This array contains server and execution environment information. Refer here for more detailed info.

We then call session_start() to give us access to the session and the set the variable $_SESSION['cf_returndata'] to mirror $returndata. On the form page, we will now be able to access this variable.

To redirect back to the form, we are using the header() function. We are telling it to redirect us to the last page we came from using the variable: $_SERVER['HTTP_REFERER'].

Altogether you should have ended up with this:

<?phpif( isset($_POST) ){    //form validation vars    $formok = true;    $errors = array();    //submission data    $ipaddress = $_SERVER['REMOTE_ADDR'];    $date = date('d/m/Y');    $time = date('H:i:s');    //form data    $name = $_POST['name'];    $email = $_POST['email'];    $telephone = $_POST['telephone'];    $enquiry = $_POST['enquiry'];    $message = $_POST['message'];    //validate form data    //validate name is not empty    if(empty($name)){        $formok = false;        $errors[] = "You have not entered a name";    }    //validate email address is not empty    if(empty($email)){        $formok = false;        $errors[] = "You have not entered an email address";    //validate email address is valid    }elseif(!filter_var($email, FILTER_VALIDATE_EMAIL)){        $formok = false;        $errors[] = "You have not entered a valid email address";    }    //validate message is not empty    if(empty($message)){        $formok = false;        $errors[] = "You have not entered a message";    }    //validate message is greater than 20 characters    elseif(strlen($message) < 20){        $formok = false;        $errors[] = "Your message must be greater than 20 characters";    }    //send email if all is ok    if($formok){        $headers = "From: [email protected]" . "\r\n";        $headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";        $emailbody = "<p>You have received a new message from the enquiries form on your website.</p>                      <p><strong>Name: </strong> {$name} </p>                      <p><strong>Email Address: </strong> {$email} </p>                      <p><strong>Telephone: </strong> {$telephone} </p>                      <p><strong>Enquiry: </strong> {$enquiry} </p>                      <p><strong>Message: </strong> {$message} </p>                      <p>This message was sent from the IP Address: {$ipaddress} on {$date} at {$time}</p>";        mail("[email protected]","New Enquiry",$emailbody,$headers);    }    //what we need to return back to our form    $returndata = array(        'posted_form_data' => array(            'name' => $name,            'email' => $email,            'telephone' => $telephone,            'enquiry' => $enquiry,            'message' => $message        ),        'form_ok' => $formok,        'errors' => $errors    );    //if this is not an ajax request    if(empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) !== 'xmlhttprequest'){        //set session variables        session_start();        $_SESSION['cf_returndata'] = $returndata;        //redirect back to form        header('location: ' . $_SERVER['HTTP_REFERER']);    }}

That’s all for processing our form submission — done and dusted in under 90 lines of PHP! All we need to do now is update the user and provide either a success message or an error message. You can save process.php now.


Step 7: Update the UI

Now that we have processed the form data and have been returned to the page, we need to update the user on what has happened. This means accessing the session variable we set on process.php and working out what response to give. Because this page now needs to use PHP, we are going to need to change the file extension of index.html to .php (index.html = index.php). Don’t worry, this should not break anything we have already done.

The first thing we need to do is get our variables out of the session. To do this, we need access to the session. Right at the top of the page before any markup (above doctype) paste the following code in:

<?php session_start() ?>

Starting the session before any content is sent to the browser should prevent any ‘cannot send session cookie – headers already sent by…’ errors you may receive. Below the H2 of the form add in this PHP snippet:

<?php//init variables$cf = array();$sr = false;if(isset($_SESSION['cf_returndata'])){    $cf = $_SESSION['cf_returndata'];    $sr = true;}?>

We are setting two variables to default values. More on these later… We are then checking to see if $_SESSION['cf_returndata'] is set. We then set $cf (short for contact form) to equal our session variable. This is just so we don’t have to type $_SESSION… every time we want to access this data. The last variable $sr (short of server response), is set to true. This is a variable we are going to be checking to see if we have previously posted our form. The next thing we want to do is display an error message or success at the top of the form. Replace this:

<ul id="errors" class="">    <li id="info">There were some problems with your form submission:</li></ul><p id="success">Thanks for your message! We will get back to you ASAP!</p>

With this:

<ul id="errors" class="<?php echo ($sr && !$cf['form_ok']) ? 'visible' : ''; ?>">    <li id="info">There were some problems with your form submission:</li>    <?php    if(isset($cf['errors']) && count($cf['errors']) > 0) :        foreach($cf['errors'] as $error) :    ?>    <li><?php echo $error ?></li>    <?php        endforeach;    endif;    ?></ul><p id="success" class="<?php echo ($sr && $cf['form_ok']) ? 'visible' : ''; ?>">Thanks for your message! We will get back to you ASAP!</p>

By default, the messages do not appear at all because, in the CSS, we’ve set 'display:none‘. Inside the class attribute of the messages, we are using PHP to add a 'visible' class to them if they are to be shown. This class sets 'display' to 'block'.

<?php echo ($sr && !$cf['form_ok']) ? 'visible' : ''; ?>

We are using the ternary operator here to check that…

  • a) the server response is equal to true and
  • b) that the form was not ok
  • .

Essentially, if we have submitted the form, $sr will equal true, and if the form was invalid $cf['form_ok'] will equal false. So the class visible will be outputted, but the PHP and message will show, and vice versa for the success message. Inside the parenthesis, we are checking the values of two variables. We are checking that $sr is equal to true and (&&) $cf['fomr_ok'] is equal to false. We are using shorthand to check these values. You could also write it this way if you wanted:

<?php echo ($sr === true && $cf['form_ok'] === false) ? 'visible' : ''; ?>

Once we have decided which message to display, we need to populate the container with the relevant data. The success message does not change, so we can leave that as it is. The error message will need populating with the validation errors. To write these out, we are simply looping through our errors array stored in the session and populating a li element inside of the ul:

<ul id="errors" class="<?php echo ($sr && !$cf['form_ok']) ? 'visible' : ''; ?>">    <li id="info">There were some problems with your form submission:</li>    <?php    if(isset($cf['errors']) && count($cf['errors']) > 0) :        foreach($cf['errors'] as $error) :    ?>    <li><?php echo $error ?></li>    <?php        endforeach;    endif;    ?></ul>

We are first checking that we have our errors array in $cf and that it contains at least one error. The if and foreach statement may look a little different to how you have seen them before. This is called Alternative Syntax. We have used alternative syntax here just to make it a little more readable with it being mixed with the HTML. You can use the normal syntax though if you like, it’s down to preference.

That’s all we need for showing the user the response of the form submission. To test this out, disable JavaScript, and submit the form. Remember that the browser will validate the form as we are using the new HTML5 elements. So to be super sure my PHP is working, I’m testing in IE8. Yes, that’s right, IE does come in handy sometimes…

If you submit the invalid form, you should get this:

Error Message

And if you fill the form in correctly, you should get:

Success Message

You should also have received an email from the code we wrote earlier (if you filled the form in correctly). Now that the form is working, the last thing we need to do is populate the form fields again with the user’s data if the submission was invalid. Swap the HTML inside of the form tags for this:

<label for="name">Name: <span class="required">*</span></label><input type="text" id="name" name="name" value="<?php echo ($sr && !$cf['form_ok']) ? $cf['posted_form_data']['name'] : '' ?>" placeholder="John Doe" required="required" autofocus="autofocus" /><label for="email">Email Address: <span class="required">*</span></label><input type="email" id="email" name="email" value="<?php echo ($sr && !$cf['form_ok']) ? $cf['posted_form_data']['email'] : '' ?>" placeholder="[email protected]" required="required" /><label for="telephone">Telephone: </label><input type="tel" id="telephone" name="telephone" value="<?php echo ($sr && !$cf['form_ok']) ? $cf['posted_form_data']['telephone'] : '' ?>" /><label for="enquiry">Enquiry: </label><select id="enquiry" name="enquiry">    <option value="General" <?php echo ($sr && !$cf['form_ok'] && $cf['posted_form_data']['enquiry'] == 'General') ? "selected='selected'" : '' ?>>General</option>    <option value="Sales" <?php echo ($sr && !$cf['form_ok'] && $cf['posted_form_data']['enquiry'] == 'Sales') ? "selected='selected'" : '' ?>>Sales</option>    <option value="Support" <?php echo ($sr && !$cf['form_ok'] && $cf['posted_form_data']['enquiry'] == 'Support') ? "selected='selected'" : '' ?>>Support</option></select><label for="message">Message: <span class="required">*</span></label><textarea id="message" name="message" placeholder="Your message must be greater than 20 charcters" required="required" data-minlength="20"><?php echo ($sr && !$cf['form_ok']) ? $cf['posted_form_data']['message'] : '' ?></textarea><span id="loading"></span><input type="submit" value="Holla!" id="submit-button" /><p id="req-field-desc"><span class="required">*</span> indicates a required field</p>

The only difference here is that we are using PHP to populate the value attribute of the inputs.

<?php echo ($sr && !$cf['form_ok']) ? $cf['posted_form_data']['name'] : '' ?>

Like we did with the success and error messages, we are checking to see if $sr is equal to true and $cf['form_ok'] is equal to false, and if they are, we write out the saved value in the session for this form field. This is done using the ternary operator.

On the select, we are doing the same, except, instead of writing out the saved value, we need to check each option value to see if it matches the one saved in the session. If it matches, we write out the selected attribute for that option.

Finally, one last thing we are going to do is unset this session variable after we’ve gotten our data from it. You don’t have to do this, though; it comes down to preference. By unsetting it now, when the page is refreshed via the refresh button (not form post), an error / success message will not be shown. If you did not unset it, a user could fill in the contact form, go potter about on the internet, come back to the form and the error / success message will still be shown. I don’t like this so I’m going to prevent it by putting this line of PHP just after the closing form tags:

<?php unset($_SESSION['cf_returndata']); ?>

If you submit an invalid form, you should notice now that your form input values are retained, and if you referesh the page, the message and data should be cleared. That’s it for the PHP side of things! You should have ended up with your form looking like so:

<div id="contact-form" class="clearfix">    <h1>Get In Touch!</h1>    <h2>Fill out our super swanky HTML5 contact form below to get in touch with us! Please provide as much information as possible for us to help you with your enquiry :) </h2>    <?php    //init variables    $cf = array();    $sr = false;    if(isset($_SESSION['cf_returndata'])){        $cf = $_SESSION['cf_returndata'];        $sr = true;    }    <ul id="errors" class="<?php echo ($sr && !$cf['form_ok']) ? 'visible' : ''; ?>">        <li id="info">There were some problems with your form submission:</li>        <?php        if(isset($cf['errors']) && count($cf['errors']) > 0) :            foreach($cf['errors'] as $error) :        ?>        <li><?php echo $error ?></li>        <?php            endforeach;        endif;        ?>    </ul>    <form method="post" action="process.php">        <label for="name">Name: <span class="required">*</span></label>        <input type="text" id="name" name="name" value="<?php echo ($sr && !$cf['form_ok']) ? $cf['posted_form_data']['name'] : '' ?>" placeholder="John Doe" required autofocus />        <label for="email">Email Address: <span class="required">*</span></label>        <input type="email" id="email" name="email" value="<?php echo ($sr && !$cf['form_ok']) ? $cf['posted_form_data']['email'] : '' ?>" placeholder="[email protected]" required />        <label for="telephone">Telephone: </label>        <input type="tel" id="telephone" name="telephone" value="<?php echo ($sr && !$cf['form_ok']) ? $cf['posted_form_data']['telephone'] : '' ?>" />        <label for="enquiry">Enquiry: </label>        <select id="enquiry" name="enquiry">            <option value="General" <?php echo ($sr && !$cf['form_ok'] && $cf['posted_form_data']['enquiry'] == 'General') ? "selected='selected'" : '' ?>>General</option>            <option value="Sales" <?php echo ($sr && !$cf['form_ok'] && $cf['posted_form_data']['enquiry'] == 'Sales') ? "selected='selected'" : '' ?>>Sales</option>            <option value="Support" <?php echo ($sr && !$cf['form_ok'] && $cf['posted_form_data']['enquiry'] == 'Support') ? "selected='selected'" : '' ?>>Support</option>        </select>        <label for="message">Message: <span class="required">*</span></label>        <textarea id="message" name="message" placeholder="Your message must be greater than 20 charcters" required data-minlength="20"><?php echo ($sr && !$cf['form_ok']) ? $cf['posted_form_data']['message'] : '' ?></textarea>        <span id="loading"></span>        <input type="submit" value="Holla!" id="submit-button" />        <p id="req-field-desc"><span class="required">*</span> indicates a required field</p>    </form>    <?php unset($_SESSION['cf_returndata']); ?></div>

Don’t forget the session_start() right at the top of the page! We now have a fully functional contact form.

The data is validated, and, if successful, we are emailed the form results. Further, we update the UI with the results for each submission. The newer browsers will even validate the form before it is submitted using the new HTML5 input types and attributes we have used.

This is all fine and dandy, but we can take things one step further. We can use JavaScript to polyfill the features that the browser does not have (built in validation, support for HTML5 attributes etc.) . We can even use JavaScript to display our error / success messages and submit the form using AJAX.

But why do this when the form already works? Well, it’s simple. We want to provide as much consistency accross all browsers as possible, even if it is a really naff browser. Also, if we get the client’s browser to handle all of the validation work, it saves our server’s resources as we’re not posting to it when the form is not valid. These things are super browny points, and really are not that difficult to do.


Step 8: What is a Polyfill?

“A polyfill, or polyfiller, is a piece of code that provides the technology that you, the developer, expect the browser to provide natively.”

In our case we expect the browser to support the new HTML5 input types and attributes we have used. Firefox, Chrome, Opera and Safari have pretty good native support for these. IE6 – 9 has no support for them at all. Typical. To be honest, it’s quite shocking IE9 does not have support for these things, it was only just released earlier this year. Anyhow, putting IE bashing aside (I could go on forever), the first two things we are going to polyfill are the autofocus and the placeholder attribute.

We’ll be using jQuery to help us out with our JavaScript. We’ll use it primarily to handle our AJAX request, animation and DOM traversal & manipulation. You could get away with not using it, but you would have to write a significant amount of code. Its footprint isn’t too big, so I can live with the file size. I, probably like you, would rather write less code.

We’ll also be using a JavaScript library called Modernizr to help us with feature detection. This is already included as part of our HTML5 boilerplate, so we don’t have to do anything here to get Modernizr up and running!

Navigate to the js directory and crack open script.js. We don’t have to worry about hooking up this file, jQuery or Modernizr, to index.php as this was already provided for us by the HTML5 boilerplate we used. Delete everything in this file and paste in the following:

$(function(){    //set global variables and cache DOM elements for reuse later    var form = $('#contact-form').find('form'),        formElements = form.find('input[type!="submit"],textarea'),        formSubmitButton = form.find('[type="submit"]'),        errorNotice = $('#errors'),        successNotice = $('#success'),        loading = $('#loading'),        errorMessages = {            required: ' is a required field',            email: 'You have not entered a valid email address for the field: ',            minlength: ' must be greater than '        }    //feature detection + polyfills    formElements.each(function(){        //do feature detection + polyfills here    });});

All our code is going to live inside the $(function(){ }) block. This will mean our code will be executed as soon as the page is loaded. Also any variables or functions we declare inside this block will not interfere with any other code outside. We are then caching some DOM elements, as we will be accessing these quite a bit. It’s more efficient to cache them in this way than to request them each time you want to use them. Here is a breakdown of what each variable is:

  • form: The contact form element.
  • formElements: All input e

    Original Link: http://feedproxy.google.com/~r/nettuts/~3/pSwhDW3Ie9Q/

    Share this article:    Share on Facebook
    View Full Article

TutsPlus - Code

Tuts+ is a site aimed at web developers and designers offering tutorials and articles on technologies, skills and techniques to improve how you design and build websites.

More About this Source Visit TutsPlus - Code