Client-side Form Validation

Introduction

Validating the inputs from a form is critical to ensuring that the data you expect is the data you receive. When done in the browser it does not require data be sent to the server prior to being validated. The term "Client-side" refers to checking data while in the browser.

Checking data in the browser is typically done using Native HTML5 Methods or using JavaScript. This document will discuss using native HTML5 methods.

Video Demonstration

The video provides a general overview of the activity, but does not contain the detail needed to complete each process. Watch the video to obtain a general idea, but follow the written steps to complete the activity. This is the Transcript of the video.

The 'required' attribute

The simplest change you can make to a form is to mark an input field as 'required':

<input type="text" name="account_firstname" required>

This informs the web browser that the field is mandatory. Most browsers will mark the input box in some way if the client fails to complete the input correctly. You can actually create your own valid/invalid formatting using CSS to override the browser default. You should be aware that the CSS pseudo-classes for doing this are currently considered experimental and may result in CSS validation errors.

Different input types

Along with the text input type, there are a host of other options, including email, url, number, tel, date and others.

On the iPhone/iPad and other mobile devices the different input types are associated with different keyboards, making it easier for people to complete your online forms. In web browsers they can be used in combination with the required attribute to limit or give advice on allowable input values. For example:

type="email"

By changing the input type to email while also using the required attribute, the browser can be used to validate (in a limited fashion) email addresses:

<input type="email" name="account_email" required placeholder="Enter a valid email address">

Note that for this example we've made use of another HTML5 attribute placeholder which lets us display a prompt or instructions inside the field - something that previously had to be done using JavaScript. Using the placeholder should NOT replace the <label> element to place a text label adjacent to the input.

HTML5 input types

Some additional, common HTML5 input types are shown below. To learn more about each one, or any of the other types, visit MDN Inputs.

Each type will prompt specific behaviors. For example, the tel input type is handy for a mobile device as it selects a different input keyboard useful for entering telephone numbers.

In most cases the browser has a built-in display and validation based on the input type, particularly when the "required" attribute is added to the input.

Patterns

The Pattern attribute adds additonal criteria when an input must meet specific requirements. Patterns are not always needed, just when a specific need exists. HTML5 patterns are actually JavaScript Regular Expressions.

Pattern Examples

IPv4 Address input pattern (four groups of up to 3 numbers separated by a period):
<input type="text" pattern="\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}">
Date input pattern (one or two digits in the first two groups, four digits in the last, all separated by slashes):
<input type="text" pattern="\d{1,2}/\d{1,2}/\d{4}">
Price input pattern (digits followed by a period, followed by two digits):
<input type="text" pattern="\d+(\.\d{2})?">

Want More Patterns?

Here are two other resources that explain more about how to use regular expressions:

Styling valid/invalid inputs using CSS

This first set of styles can be used to mark an input box as 'invalid', by adding an icon, coloring the text or borders or similar. It will apply to inputs that are required but empty, or to inputs that have a required format/pattern which hasn't yet been met. These pseudo-classes were considered experimental, but no longer are. Their use should now pass CSS validation.

input:required:invalid, input:focus:invalid {
 /* insert your own styles for invalid form input */
}

For inputs that are both required and 'valid' you can use the following:

input:required:valid {
 /* insert your own styles for valid form input */
}

Sample styling using images and sprites

As shown above, once you've added HTML5 attributes to your form elements, they can be easily styled using CSS so that each input field is clearly marked as valid or invalid. This also works for textarea elements.

input:required:invalid, input:focus:invalid {
 background-image: url(/images/invalid.png);
 background-position: right top;
 background-repeat: no-repeat;
}
 input:required:valid {
 background-image: url(/images/valid.png);
 background-position: right top;
 background-repeat: no-repeat;
 }

Apply Validation

With a basic introduction to HTML5 validation established let's apply it to the registration and login views.

The Registration View

  1. Open the registration view in the editor to alter its code.
  2. Since all fields are "required" make sure you add the "required" attribute to all four data input fields (e.g. first name, last name, email and password).
  3. Make sure each of the fields has the right type value.
    • First name and Last name are both "text".
    • Email is type "email".
    • Password is type "password".
  4. Let's add a pattern to the password field to make sure the password is at least 12 characters and has at least 1 uppercase character, 1 number and 1 special character.
    • Add a <div> element near the password input. Include the password requirements in the div. Use CSS to style it so that it is easily read before the input is typed.
    • Add the pattern attribute and the regular expression to the password input: pattern="^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[^a-zA-Z0-9])(?!.*\s).{12,}$".
    This reads, "There must be at least 12 characters, one must be a number, one must be a lowercase letter, one must be a capital letter, and one must be a non-alphanumeric character."
  5. When done, the password input could look something like this:
    <label for="accountPassword">Password:</label>
    <span>Passwords must be at least 12 characters and contain at least 1 number, 1 capital letter and 1 special character</span>
    <input type="password" name="account_password" id="accountPassword" required pattern="^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[^a-zA-Z0-9])(?!.*\s).{12,}$">

Test It

  1. Save the registration view and make sure your servers are running.
  2. Launch the project home page and navigate through the login view to the registration view.
  3. Try submitting the view with no data. It should not allow it.
  4. Then try submitting the view with broken data in the email and password fields. Again, the form should stop and tell you to fix errors.
  5. Finally, try submitting the form with good data. This time no errors should appear.

The Login View

  1. Open the login view in VSC to alter the form code.
  2. Make sure the email input type is "email".
  3. Add the "required" attribute to the email and password inputs.
  4. Add the same reminder as you have in the registration view to the login view about the password requirements.
  5. Add the same pattern attribute to the password field in this view as you have in the registration view.

Test It

  1. Save the login view and make sure the server is running.
  2. Launch the project home page and navigate to the login view.
  3. Try submitting the view with no data. It should not work.
  4. Then try submitting the view with broken data in the email and password fields. Again, the form should stop and tell you to fix errors.
  5. Finally, try submitting the form with good data. This time no errors should appear. But, since the login process is not operational, it should do nothing.

Summary

As you have seen, with relatively little effort we can add HTML attributes and values to forms to make sure data is the right kind in most cases or at least not missing in others.

The "fly in the ointment" is that client-side validation can be turned off in the browser. JaveScript can be disabled and using tools such as the novalidate! bookmarklet (the installation of which will be done in its own activity this week) can disable client-side validation. As a result, we cannot rely solely on client-side validation, we MUST also have "server-side" validation and that is what we will implement in the next activity.

Reference

Attribution

This native html5 form validation explanation was originally created by David Nielsen, a Frontend Web Development student as a teaching presentation during the Fall semester, 2013.