A matter of <form>

When I redesigned iandevlin.com as a business-card style website, I was a bit lazy when it came to the contact form. Other than making it snazzily slide down when the @ symbol graphic is clicked on, I didn’t do much else with it, leaving it the way it was – using a CGI script to send the email (I know! Seriously!)

I always had the intention of changing it but never actually got around to doing it for various reasons that range from just not being bothered to being lazy. But after reading a form of madness over at Dive Into HTML5, I decided that the time had come to actually get on with it, and to make use some of the new elements within html5. And so I have.

Decisions, decisions

To begin with, since I had already converted the site to HTML5, I wanted to take advantage of the new tags that HTML5 offered. Granted most browsers will simply ignore them, but it’s nice to have them in place and to get used to using them.

Since the site itself is contained within the one HTML page, I also wanted to use AJAX to provide some on page feedback if the form was filled out incorrectly, if the sending failed or of course, if it succeeded. I’m aware that there are plenty of existing JavaScript plugins out there that already do all this, and since the site already uses JQuery for the sliding effect, I still wanted to write my own AJAX routine, since I had been using it recently whilst writing the chat feature for the Wildlifefocus website (which is nearing completion).

HTML5 form

I won’t go into all the new form elements that HTML5 offers, you can read about them in a form of madness and/or in the HTML5 specification itself. Here I will just mention the items that I have used which are as follows:

Note, that for HTML5 compliancy, the <input> elements do not have closing tags.

AJAX and PHP

With the form markup out of the way, it was time to tackle the validation and submitting of the email itself, which isn’t actually that difficult at all and I’ll simply show you here what I’ve done.

The form action itself calls a JavaScript function which collects the parameters, and calls the sendmail.php page (described below) to send the email. The sendEmail JavaScript function looks like this:

function sendEmail(obj) {
  var params = "";
  if (obj.elements.name != "") {
    params += (params=='')?'?':'&';
    params += "name=" + escape(obj.elements.name.value);
  }
  if (obj.elements.emailaddr != "") {
    params += (params=='')?'?':'&';
    params += "emailaddr=" + escape(obj.elements.emailaddr.value);
  }
  if (obj.elements.subject != "") {
    params += (params=='')?'?':'&';
    params += "subject=" + escape(obj.elements.subject.value);
  }
  if (obj.elements.message != "") {
    params += (params=='')?'?':'&';
    params += "message=" + escape(obj.elements.message.value);
  }

  if (params != "") {
    xmlhttp = GetXmlHttpObj();
    if (xmlhttp == null) {
      alert ("Your browser does not support XMLHTTP!");
      return;
    }
    var url = "sendemail.php" + params;
    xmlhttp.onreadystatechange = sendEmailStateChanged;
    xmlhttp.open("POST", url, true);
    xmlhttp.send(null);
  }
}

GetXmlHttpObj() returns the appropriate Xml Http object for the browser as follows:

function GetXmlHttpObj() {
  if (window.XMLHttpRequest) return new XMLHttpRequest();
  if (window.ActiveXObject) return new ActiveXObject("Microsoft.XMLHTTP");
  else return null;
}

The function sendEmailStateChanged() which displays the result of the email sending once the state has changed is:

function sendEmailStateChanged() {
   if (xmlhttp.readyState == 4) {
     var response = xmlhttp.responseText;
     if (response == "ok") {
       document.getElementById("emailcontainer").innerHTML = "Thanks";
     }
     else {
       document.getElementById("formerror").style.display = "block";
       document.getElementById("formerror").innerHTML = response;
     }
  }
}

To replace the old CGI script, I created a simple PHP page that handles the actual sending of the email. It parses the incoming arguments and validates them, adding to an error string if anything is amiss (missing fields, invalid email address) and either sends the email or returns the error string for AJAX to display above the form:

<?php
&nbsp;&nbsp;require("lib/lib_email.php");

&nbsp;&nbsp;$temp_name = $_GET["name"];
&nbsp;&nbsp;$temp_email = $_GET["emailaddr"];
&nbsp;&nbsp;$temp_subject = $_GET["subject"];
&nbsp;&nbsp;$temp_message = $_GET["message"];

&nbsp;&nbsp;$name = trim($temp_name);
&nbsp;&nbsp;$email = trim($temp_email);
&nbsp;&nbsp;$subject = trim($temp_subject);
&nbsp;&nbsp;$message = trim($temp_message);

&nbsp;&nbsp;$return_msg = "";

&nbsp;&nbsp;if ($name == "") $return_msg .= "enter your name";
&nbsp;&nbsp;if ($email == "") $return_msg .= "enter your email";
&nbsp;&nbsp;else if (!is_email_address_valid($email)) {
&nbsp;&nbsp;&nbsp;&nbsp;$return_msg .= "enter a valid email address";
&nbsp;&nbsp;}
&nbsp;&nbsp;if ($subject == "") $return_msg .= "enter a subject";
&nbsp;&nbsp;if ($message == "") $return_msg .= "enter a message";

&nbsp;&nbsp;if ($return_msg == "") {
&nbsp;&nbsp;&nbsp;&nbsp;$headers = "From: " . $email . "\r\n";
&nbsp;&nbsp;&nbsp;&nbsp;$to = "name@emailaddress.com";
&nbsp;&nbsp;&nbsp;&nbsp;$message = str_replace("\n.", "\n..", $message);
&nbsp;&nbsp;&nbsp;&nbsp;if (!mail($to, $subject, $message, $headers)) [
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print "error sending mail";
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;else print "ok";
&nbsp;&nbsp;}
&nbsp;&nbsp;else print $return_msg;
?>

Note that lib_email.php contains the is_email_address_valid() function that validates the email address using regular expressions. Also, there’s not much sanitisation performed on the parameters since they’re not being added to a database so it’s not that important here.

And there you have it. A simple HTML5 compatible contact form that uses AJAX and PHP to send an email.