Build better forms with jQuery and CSS

Posted on Saturday September 08, 2012 / by Eric Potvin

Reloading a web form to display errors is something we had to do long time ago. Does your website still has a form that does not display errors right away? If so, it is time for a change.

jQuery (and jQuery validation) provides all the tools you need to display any errors to the users. The concept is very simple, each field can be validated simply by using a "class". For example:

<input /* ... */ class="email" />

This one will validate if a valid email is entered ni the input field and display right away if the email is valid or not without refreshing the page.

Requirements:

Now that we have included the mandatory files, we have to build rules for our form. Let's create a simple form with an email field, first name, last name, 3 radio buttons and 1 (one) checkbox.

<input type="text" name="email" id="email" maxlength="80" size="30" value="" class="required email" />
<input type="text" name="first" id="first" maxlength="30" size="30" value="" class="required" />
<input type="text" name="last" id="last" maxlength="30" size="30" value="" class="required" />

<input type="radio" name="browser" class="required" />Firefox
<input type="radio" name="browser" />Chrome
<input type="radio" name="browser" />Safari

<input type="checkbox" name="privacy" id="privacy" value="y" class="required" />

In this case, each fields are required and the email field has a email validation. The beauty of this validation is nothing else on the form is required to validate those fields. All the code is build in a separate JavaScript file.

To start, we have to declare the validation of the form itself, otherwise nothing will work.

$("form").validate({
  errorClass: "errorForm",
  rules: { },
  messages: { }
});

That will take care of the class="required". Automatically, the jQuery validator will handle these and put the message above or bellow (depending on how you want to display it). Now, let's add the email validation.

$(".email").each(function() {
  $(this).rules("add", {
    required: true,
    email: true,
    minlength: 8,
    messages: {
      required: "Please enter your email",
    }
  });
});

Now, email has to be treated differently from other fields since it needs to make sure an email is entered. jQuery validator has all the code to validate the email, the only difference here is you have to tell him which field is an email.

Now, that we have our main fields set-up, we have to create the JavaScript code that will handle the submit button. That button will simply call the validation (we created above) and return true or false.

var valid = $("form").valid();

This one will automatically show the errors on the page. Would it be nice to focus on the first error? Yes. In case of an error, it would be nice to focus on the field and not let the user search for it.

if(!valid) {
  $('#' + $('input.errorForm:first').attr('id')).focus();
  return false;
}

Make it look nice.

Now, remember we had a errorClass: "errorForm" predefine when we declared our validation? This is will tell the jQuery validator which class to use to display or change the fields (to make it more obvious to the user).

input.errorForm, select.errorForm {
  background: #ffdede;
  color: red;
  border: solid 1px red;
  /* and other declaration */
}
label.errorForm {
  color: red;
  font-size: 10px;
  /* and other declaration */
}

This way, the fields with errors are easy to find. jQuery validator has a great advantage, it is very customizable. Here's a example of adding a validation that does not allow spaces in the field.

The full scripts:

$(document).ready(function() {
  $("form").validate({
    errorClass: "errorForm",
    rules: { },
    messages: { }
  });
  $(".email").each(function() {
    $(this).rules("add", {
      required: true,
      email: true,
      minlength: 8,
      messages: {
        required: "Please enter your email",
      }
    });
  });
  $('input[type=button]').click(function() {
    var valid = $("form").valid();
    if(!valid) {
      var id = $('input.errorForm:first').attr('id');
      $('#' + id).focus();
      return false;
    }
    return true;
  });
});