Before submitting data to the server, it is important to ensure required form controls are filled in and that all the form controls are filled out in the correct format. This client-side form validation helps ensure data submitted matches the requirements set forth in the various form controls. This article leads you through basic concepts and examples of client-side form validation.
Client side validation is an initial check and an important feature of good user experience; by catching and requiring corrections to invalid data before it is sent to the server to be rejected there, the delay caused by a round trip to the server for server-side validation is avoided. Server-side validation is still necessary to check data sent to the server, ensuring incorrect or malicious data is rejected. Server-side validation is beyond the scope of this guide.
This tutorial is a brief introduction to native and scripted client-side validation; just an overview of what is possible and what is needed. For more information beyond this tutorial, see the Constraint validation guide.
Prerequisites: | Computer literacy, a reasonable understanding of HTML, CSS, and JavaScript. |
---|---|
Objective: | To understand what form validation is, why it's important, and to apply various techniques to implement it. |
What is form validation?
Go to any popular site with a registration form, and you will notice that they provide feedback when you don't enter your data in the format they are expecting. You'll get messages such as:
- "This field is required" (You can't leave this field blank.)
- "Please enter your phone number in the format xxx-xxxx" (The form enforces a pattern of three numbers followed by a dash, followed by four numbers.)
- "Please enter a valid email address" (Used if your entry is not the right type; not in the format of "somebody@example.com")
- "Your password needs to be between 8 and 30 characters long and contain one uppercase letter, one symbol, and a number." (When the length is shorter than the
minlength
or longer than themaxlength
attributes, or otherwised doesn't match an includedpattern
attribute or a regular expression comparison done with JavaScript).
This is called form validation. When you enter data, the browser and, optionally, the web application, check to see that the data is in the correct format and within the constraints set by the various validation-related attributes. If the information is correctly formatted, the user agent (and application) allows the data to be submitted to the server and (usually) saved in a database; if the information isn't correctly formatted, it gives the usr an error message explaining what needs to be corrected.
We want to make filling out web forms as easy as possible. So why do we insist on validating our forms? There are three main reasons:
- We want to get the right data, in the right format. Our applications won't work properly if our users' data is stored in the incorrect format, if they don't enter the correct information, or if they omit information altogether.
- We want to protect our users' accounts. Forcing our users to enter secure passwords makes it easier to protect their account information.
- We want to protect ourselves. There are many ways that malicious users can misuse unprotected forms to damage the application. (See Website security.)
Warning: Never trust data passed to your server from the client. Even if your form is validating correctly and preventing malformed input on the client-side, a malicious user can still alter the network request.
Different types of form validation
There are two different types of form validation that you'll encounter on the web:
- Client-side validation is validation that occurs in the browser before the data has been submitted to the server. Client-side validation is more user-friendly than server-side validation because it gives an instant response. Client-side validation is further subdivided into the following categories:
- JavaScript validation is coded using JavaScript. This validation is completely customizable.
- Built-in form validation uses HTML5 form validation features. This validation generally doesn't require JavaScript. Built-in form validation has better performance than JavaScript. But, while highly customizable, native validation is not as customizable as JavaScript.
- Server-side validation is validation that occurs on the server after the data has been submitted. Server-side code is used to validate the data before the data is saved in the database or otherwise used by the application. If the data fails validation, a response is sent back to the client with corrections that the user needs to make. Server-side validation is your application's last line of defense against incorrect or malicious data. All popular server-side frameworks have features for validating and sanitizing data, or making it safe.
For good user experience and security, developers should use a combination of both client-side and server-side validation. Client-side validation is more user-friendly than server-side validation because it provides errors during form completion rather than requiring the entire form to be completed, submitted, analyzed, and returned. Server-side validation should be considered required because client-side error checking can be bypassed and network requests can be altered.
Using built-in form validation
One of the features of HTML5 form controls is the ability to validate most user data without relying on scripts. This is done by using validation attributes on form elements. Validation attributes allow you to specify rules for a form input, such as whether a value must be filled in (the required
attribute); the minimum and maximum length of the data (the minlength
and maxlength
attributes); the minimum and maximum values (the min
and max
attributes); whether the data needs to be a number, an email address, or something else (the type
attribute); and a regular expression pattern that the data must match (the pattern
attribute). In supporting browsers, if the entered data follows all of the specified rules, it is considered valid; if not, it is considered invalid.
When an element is valid, the following things are true:
- The element matches the
:valid
CSS pseudo-class, which lets you apply a specific style to valid elements. - If the user tries to send the data, the browser will submit the form, provided there is nothing else stopping it from doing so (e.g., JavaScript).
When an element is invalid, the following things are true:
- The element matches the
:invalid
CSS pseudo-class, and sometimes other UI pseudo-classes depending on the error, which lets you apply a specific style to invalid elements. - If the user tries to send the data, the browser will block the form and display an error message.
There are several errors that will prevent the form from being submitted, including a badInput
, a patternMismatch
, a rangeOverflow
or underFlow
, a stepMismatch
, a form control that is tooLong
or tooShort
, a typeMismatch
, and valueMissing
that is required, and even just having a customError
,
Validation constraints on input elements
In this section, we'll look at some of the different form control attributes that can be used to validate <input>
elements.
Let's start with a simple example: an input that allows you to choose whether you prefer a banana or a cherry. This example involves a simple text <input>
with an associated <label>
and a submit <button>
. Find the source code on GitHub at fruit-start.html and a live example below.
<form> <label for="choose">Would you prefer a banana or cherry?</label> <input id="choose" name="i_like"> <button>Submit</button> </form>
input:invalid { border: 2px dashed red; } input:valid { border: 2px solid black; }
To begin, make a copy of fruit-start.html
in a new directory on your hard drive.
The required attribute
The simplest HTML5 validation feature is the required
attribute. To make an input mandatory, mark the element with this attribute. When this attribute is set, the element matches the :required
UI pseudo-class and the form won't submit -- displaying an error message on submission -- when the input is empty. While empty, the input will also be considered invalid, matching the :invalid
UI pseudo-class.
Add a required
attribute to your input, as shown below.
<form> <label for="choose">Would you prefer a banana or cherry? (required)</label> <input id="choose" name="i_like" required> <button>Submit</button> </form>
Note the CSS that is included in the example file:
input:invalid { border: 2px dashed red; } input:invalid:required { background-image: linear-gradient(to right, pink, lightgreen); } input:valid { border: 2px solid black; }
This CSS causes the input to have a red dashed border when it is invalid and a more subtle solid black border when valid. We also added a background gradient when required and invalid to demonstrate the :required
pseudo-class. Try out the new behavior in the example below.
The presence of the required
attribute on any element that supports this attribute means the element matches the :required
pseudoclass whether it has a value or not. If the <input>
has no value, the input
will match the :invalid
pseudoclass, and the element.validity.valueMissing
will return true
during constraint validation.
Note: For good user experience, indicate to the user when form fields are required. It isn't only good user experience, it is required by WCAG accessibility guidelines. Also, only require users to input data you actually need: For example, why do you really need to know someone's gender or title?
Try submitting the form without a value. Note how the invalid input gets focus, a default error message ("Please fill out this field") appears, and the form is prevented from being sent.
Validating against a regular expression
Another useful validation feature is the pattern
attribute, which expects a Regular Expression as its value. A regular expression (regex) is a pattern that can be used to match character combinations in text strings, so regexs are ideal for form validation and serve a variety of other uses in JavaScript.
Regexs are quite complex, and we don't intend to teach you them exhaustively in this article. Below are some examples to give you a basic idea of how they work.
a
— Matches one character that isa
(notb
, notaa
, and so on).abc
— Matchesa
, followed byb
, followed byc
.ab?c
—Matchesa
, optionally followed by a singleb
, followed byc
. (ac
orabc
)ab*c
—Matchesa
, optionally followed by any number ofb
s, followed byc
. (ac
,abc
,abbbbbc
, and so on).a|b
— Matches one character that isa
orb
.abc|xyz
— Matches exactlyabc
or exactlyxyz
(but notabcxyz
ora
ory
, and so on).- There are many more possibilities that we don't need to cover here.
Let's implement an example. Update your HTML to add a pattern
attribute like this:
<form> <label for="choose">Would you prefer a banana or a cherry?</label> <input id="choose" name="i_like" required pattern="banana|cherry"> <button>Submit</button> </form>
input:invalid { border: 2px dashed red; } input:valid { border: 2px solid black; }
In this example, the <input>
element accepts one of two possible values: the string "banana" or the string "cherry"; both case-sensitive (For learning purposes only; terrible user experience).
At this point, try changing the value inside the pattern
attribute to equal some of the examples you saw earlier, and look at how that affects the values you can enter to make the input value valid. Try writing some of your own, and see how it goes. Make them fruit-related where possible so that your examples make sense!
If a non-empty value of the <input>
doesn't match the regular expression's pattern, the input
will match the :invalid
pseudoclass, and the theInput.validity.patternMismatch
will return true
when the form is submitted.
The patternMismatch
returns true if the element's value doesn't match the provided pattern; false otherwise. When true, the form will be prevented from being submitted in supporting browsers.
Note: Some <input>
element types don't need a pattern
attribute to be validated. Specifying the email
type, for example, validates the inputs value against a regular expression matching a well-formed email address or a comma-separated list of email addresses if it has the multiple
attribute. As a further example, fields with the url
type require a properly formed URL.
Note: The <textarea>
element doesn't support the pattern
attribute.
Constraining the length of your entries
You can constrain the character length of all text fields created by <input>
or <textarea>
by using the minlength
and maxlength
attributes. A field is invalid - (tooShort
) - if it has a value and that value has fewer characters than the minlength
value or longer than the maxlength
value - (tooLong
).
Browsers often don't let the user type a longer value than expected into text fields. A better user experience to maxlength
- to not being allowed to enter more than a limited number of characters - is to allow the user to enter text, providing character count feedback in an accessible manner and letting them edit their content down to size. An example of this is the character limit when Tweeting. JavaScript, including solutions using maxlength
, can be used.
Constraining the values of your entries
For number fields (i.e. <input type="number">
), the min
and max
attributes also provide a validation constraint. If the field's value is lower than the min
attribute the rangeUnderflow
returns true. If higher than the max
attribute, rangeOverflow
returns true. Either way, the field will be invalid.
Let's look at another example. Create a new copy of the fruit-start.html file.
Now delete the contents of the <body>
element, and replace it with the following:
<form> <div> <label for="choose">Would you prefer a banana or a cherry?</label> <input type="text" id="choose" name="i_like" required minlength="6" maxlength="6"> </div> <div> <label for="number">How many would you like?</label> <input type="number" id="number" name="amount" value="1" min="1" max="10"> </div> <div> <button>Submit</button> </div> </form>
- Here you'll see that we've given the
text
field aminlength
andmaxlength
of six, which is the same length as banana and cherry. Entering fewer characters will show as invalid andelement.validity.tooShort
will return true upon constraint validation. Entering more characters is not possible in most browsers, butelement.validity.tooLong
would return true. - We've also given the
number
field amin
of one and amax
of ten. Entered numbers outside this range will show as invalid; users won't be able to use the increment/decrement arrows to move the value outside of this range. If the user manually enters a number outside of this range, constraint validation will return true for eitherelement.validity.rangeUnderflow
orelement.validity.rangeOverflow
. Thestep
attribute defaults to1
, meaning floats, like 3.2, will also show as invalid, returningtrue
forstepMismatch
during constraint validation. The number is not required, so removing the value is valid; neither astepMismatch
nor arangeUnderflow
input:invalid { border: 2px dashed red; } input:valid { border: 2px solid black; } div { margin-bottom: 10px; }
Here is the example running live:
Note: <input type="number">
(and other types, such as range
and date
) can also take a step
attribute, which specifies what increment the value will go up or down by when the input controls are used (such as the up and down number buttons).
Full example
Here is a full example to show usage of HTML's built-in validation features.
<form> <p> <fieldset> <legend>Do you have a driver's license?<abbr title="This field is mandatory" aria-label="required">*</abbr></legend> <!-- While only one radio button in a same-named group can be selected at a time, and therefore only one radio button in a same-named group having the "required" attribute suffices in making a selection a requirement --> <input type="radio" required name="driver" id="r1" value="yes"><label for="r1">Yes</label> <input type="radio" required name="driver" id="r2" value="no"><label for="r2">No</label> </fieldset> </p> <p> <label for="n1">How old are you?</label> <!-- The pattern attribute can act as a fallback for browsers which don't implement the number input type but support the pattern attribute. Please note that browsers that support the pattern attribute will make it fail silently when used with a number field. Its usage here acts only as a fallback --> <input type="number" min="12" max="120" step="1" id="n1" name="age" pattern="\d+"> </p> <p> <label for="t1">What's your favorite fruit?<abbr title="This field is mandatory" aria-label="required">*</abbr></label> <input type="text" id="t1" name="fruit" list="l1" required pattern="[Bb]anana|[Cc]herry|[Aa]pple|[Ss]trawberry|[Ll]emon|[Oo]range"> <datalist id="l1"> <option>Banana</option> <option>Cherry</option> <option>Apple</option> <option>Strawberry</option> <option>Lemon</option> <option>Orange</option> </datalist> </p> <p> <label for="t2">What's your e-mail address?</label> <input type="email" id="t2" name="email"> </p> <p> <label for="t3">Leave a short message</label> <textarea id="t3" name="msg" maxlength="140" rows="5"></textarea> </p> <p> <button>Submit</button> </p> </form>
form { font: 1em sans-serif; max-width: 320px; } p > label { display: block; } input[type="text"], input[type="email"], input[type="number"], textarea, fieldset { width : 100%; border: 1px solid #333; box-sizing: border-box; } input:invalid { box-shadow: 0 0 5px 1px red; } input:focus:invalid { box-shadow: none; }
See Validation-related attributes for a complete list of attributes that can be used to constrain input values and the input types that support them.
Note: This example was created for illustrative purposes. Use the most apporpriate form control for the data required. If you are limiting the values to a defined set of values, as we have done with fruit, use a <select>
.
Customized error messages
As you saw in the examples above, each time a user tries to submit an invalid form, the browser displays an error message. The way this message is displayed depends on the browser.
These automated messages have two drawbacks:
- There is no standard way to change their look and feel with CSS.
- They depend on the browser locale, which means that you can have a page in one language but an error message displayed in another language.
Browser | Rendering |
---|---|
Firefox 17 (Windows 7) | ![]() |
Chrome 22 (Windows 7) | ![]() |
Opera 12.10 (Mac OSX) | ![]() |
To customize the text of these messages, you must use JavaScript; there is no way to do it using only HTML and CSS.
HTML5 provides the constraint validation API to check and customize the state of a form element. Here's a brief example of changing the text of the error message.:
<form> <label for="mail">I would like you to provide me an e-mail</label> <input type="email" id="mail" name="mail"> <button>Submit</button> </form>
In JavaScript, you call the setCustomValidity()
method:
const email = document.getElementById("mail"); email.addEventListener("input", function (event) { if (email.validity.typeMismatch) { email.setCustomValidity("I am expecting an e-mail!"); } else { email.setCustomValidity(""); } });
Note: if you set a custom validity message you must set the custom validity message to the empty string when the value is valid or the form will never be submitted.
Validating forms using JavaScript
You must use JavaScript if you want to take control over the look and feel of native error messages or to deal with legacy browsers that do not support HTML's built-in form validation.
The constraint validation API
Most browsers support the constraint validation API. This API consists of a set of methods and properties available on specific form element interfaces:
HTMLButtonElement
HTMLFieldSetElement
HTMLInputElement
HTMLOutputElement
HTMLSelectElement
HTMLTextAreaElement
Constraint validation API properties
Property | Description |
---|---|
validationMessage |
A localized message describing the validation constraints that the control doesn't satisfy (if any) or the empty string if the control is not a candidate for constraint validation (willValidate is false ) or the element's value satisfies its constraints. |
validity |
A ValidityState object describing the validity state of the element. See that article for details of possible validity states. |
willValidate |
Returns true if the element will be validated when the form is submitted; false otherwise. |
Constraint validation API methods
Method | Description |
---|---|
checkValidity() |
Returns true if the element's value has no validity problems; false otherwise. If the element is invalid, this method also causes an invalid event at the element. |
HTMLFormElement.reportValidity() |
Returns true if the element or its child controls satisfy validation constraints. When false is returned, cancelable invalid events are fired for each invalid element and validation problems are reported to the user. |
setCustomValidity(message) |
Adds a custom error message to the element; if you set a custom error message, the element is considered to be invalid, and the specified error is displayed. This lets you use JavaScript code to establish a validation failure other than those offered by the standard constraint validation API. The message is shown to the user when reporting the problem. If the argument is the empty string, the custom error is cleared. |
For legacy browsers, it's possible to use a polyfill such as Hyperform to compensate for the lack of support for the constraint validation API. Because you're already using JavaScript, using a polyfill isn't an added burden to your website or web application's design or implementation.
Example using the constraint validation API
Let's see how to use this API to build custom error messages. First, the HTML:
<form novalidate> <p> <label for="mail"> <span>Please enter an email address:</span> <input type="email" id="mail" name="mail"> <span class="error" aria-live="polite"></span> </label> </p> <button>Submit</button> </form>
This simple form uses the novalidate
attribute to turn off the browser's automatic validation; this lets our script take control over validation. However, this doesn't disable support for the constraint validation API nor the application of the CSS pseudo-class :valid
, :invalid
, :in-range
and :out-of-range
classes. That means that even though the browser doesn't automatically check the validity of the form before sending its data, you can still do it yourself and style the form accordingly.
The aria-live
attribute makes sure that our custom error message will be presented to everyone, including those using assistive technologies, such as screen readers.
CSS
This CSS styles our form and the error output to look more attractive.
/* This is just to make the example nicer */ body { font: 1em sans-serif; padding: 0; margin : 0; } form { max-width: 200px; } p * { display: block; } input[type=email]{ -webkit-appearance: none; width: 100%; border: 1px solid #333; margin: 0; font-family: inherit; font-size: 90%; box-sizing: border-box; } /* This is our style for the invalid fields */ input:invalid{ border-color: #900; background-color: #FDD; } input:focus:invalid { outline: none; } /* This is the style of our error messages */ .error { width : 100%; padding: 0; font-size: 80%; color: white; background-color: #900; border-radius: 0 0 5px 5px; box-sizing: border-box; } .error.active { padding: 0.3em; }
JavaScript
The following JavaScript code handles the custom error validation.
// There are many ways to pick a DOM node; here we get the form itself and the email // input box, as well as the span element into which we will place the error message. const form = document.getElementsByTagName('form')[0]; const email = document.getElementById('mail'); const error = document.querySelector('.error'); email.addEventListener("input", function (event) { // Each time the user types something, we check if the // email field is valid. if (email.validity.valid) { // In case there is an error message visible, if the field // is valid, we remove the error message. error.innerHTML = ""; // Reset the content of the message error.className = "error"; // Reset the visual state of the message } }, false); form.addEventListener("submit", function (event) { // Each time the user tries to send the data, we check // if the email field is valid. if (!email.validity.valid) { // If the field is not valid, we display a custom // error message. error.innerHTML = "I expect an e-mail."; error.className = "error active"; // And we prevent the form from being sent by canceling the event event.preventDefault(); } }, false);
Here is the live result:
The constraint validation API gives you a powerful tool to handle form validation, letting you have enormous control over the user interface above and beyond what you can do with HTML and CSS alone.
Validating forms without a built-in API
Sometimes, such as with legacy browsers or custom widgets, you won't be able to or won't want to use the constraint validation API. In that case, you're still able to use JavaScript to validate your form. Validating a form is more a question of user interface than real data validation.
To validate a form, ask yourself a few questions:
- What kind of validation should I perform?
- You need to determine how to validate your data: string operations, type conversion, regular expressions, and so on. It's up to you. Just remember that form data is always text and is always provided to your script as strings.
- What should I do if the form doesn't validate?
- This is clearly a UI matter. You have to decide how the form will behave. Does the form send the data anyway? Should you highlight the fields that are in error? Should you display error messages?
- How can I help the user to correct invalid data?
- In order to reduce the user's frustration, it's very important to provide as much helpful information as possible in order to guide them in correcting their inputs. You should offer up-front suggestions so they know what's expected, as well as clear error messages. If you want to dig into form validation UI requirements, there are some useful articles you should read:
- SmashingMagazine: Form-Field Validation: The Errors-Only Approach
- SmashingMagazine: Web Form Validation: Best Practices and Tutorials
- Six Revision: Best Practices for Hints and Validation in Web Forms
- A List Apart: Inline Validation in Web Forms
An example that doesn't use the constraint validation API
In order to illustrate this, let's rebuild the previous example so that it works with legacy browsers:
<form> <p> <label for="mail"> <span>Please enter an email address:</span> <input type="text" class="mail" id="mail" name="mail"> <span class="error" aria-live="polite"></span> </label> <p> <!-- Some legacy browsers need to have the `type` attribute explicitly set to `submit` on the `button`element --> <button type="submit">Submit</button> </form>
As you can see, the HTML is almost the same; we just removed the HTML validation features. Note that ARIA is an independent specification that's not specifically related to HTML5.
CSS
Similarly, the CSS doesn't need to change very much; we just turn the :invalid
CSS pseudo-class into a real class and avoid using the attribute selector that doesn't work on Internet Explorer 6.
/* This is just to make the example nicer */ body { font: 1em sans-serif; padding: 0; margin : 0; } form { max-width: 200px; } p * { display: block; } input.mail { -webkit-appearance: none; width: 100%; border: 1px solid #333; margin: 0; font-family: inherit; font-size: 90%; box-sizing: border-box; } /* This is our style for the invalid fields */ input.invalid{ border-color: #900; background-color: #FDD; } input:focus.invalid { outline: none; } /* This is the style of our error messages */ .error { width : 100%; padding: 0; font-size: 80%; color: white; background-color: #900; border-radius: 0 0 5px 5px; box-sizing: border-box; } .error.active { padding: 0.3em; }
JavaScript
The big changes are in the JavaScript code, which needs to do much more of the heavy lifting.
// There are fewer ways to pick a DOM node with legacy browsers const form = document.getElementsByTagName('form')[0]; const email = document.getElementById('mail'); // The following is a trick to reach the next sibling Element node in the DOM // This is dangerous because you can easily build an infinite loop. // In modern browsers, you should prefer using element.nextElementSibling let error = email; while ((error = error.nextSibling).nodeType != 1); // As per the HTML5 Specification const emailRegExp = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/; // Many legacy browsers do not support the addEventListener method. // Here is a simple way to handle this; it's far from the only one. function addEvent(element, event, callback) { let previousEventCallBack = element["on"+event]; element["on"+event] = function (e) { const output = callback(e); // A callback that returns `false` stops the callback chain // and interrupts the execution of the event callback. if (output === false) return false; if (typeof previousEventCallBack === 'function') { output = previousEventCallBack(e); if(output === false) return false; } } }; // Now we can rebuild our validation constraint // Because we do not rely on CSS pseudo-class, we have to // explicitly set the valid/invalid class on our email field addEvent(window, "load", function () { // Here, we test if the field is empty (remember, the field is not required) // If it is not, we check if its content is a well-formed e-mail address. const test = email.value.length === 0 || emailRegExp.test(email.value); email.className = test ? "valid" : "invalid"; }); // This defines what happens when the user types in the field addEvent(email, "input", function () { const test = email.value.length === 0 || emailRegExp.test(email.value); if (test) { email.className = "valid"; error.innerHTML = ""; error.className = "error"; } else { email.className = "invalid"; } }); // This defines what happens when the user tries to submit the data addEvent(form, "submit", function () { const test = email.value.length === 0 || emailRegExp.test(email.value); if (!test) { email.className = "invalid"; error.innerHTML = "I expect an e-mail, darling!"; error.className = "error active"; // Some legacy browsers do not support the event.preventDefault() method return false; } else { email.className = "valid"; error.innerHTML = ""; error.className = "error"; } });
The result looks like this:
As you can see, it's not that hard to build a validation system on your own. The difficult part is to make it generic enough to use it both cross-platform and on any form you might create. There are many libraries available to perform form validation; you shouldn't hesitate to use them. Here are a few examples:
- Standalone library
- jQuery plug-in:
Remote validation
In some cases, it can be useful to perform some remote validation. This kind of validation is necessary when the data entered by the user is tied to additional data stored on the server side of your application. One use case for this is registration forms, where you ask for a username. To avoid duplication, it's smarter to perform an AJAX request to check the availability of the username rather than asking the user to send the data and then sending back the form with an error.
Performing such a validation requires taking a few precautions:
- It requires exposing an API and some data publicly; be sure it is not sensitive data.
- Network lag requires performing asynchronous validation. This requires some UI work in order to be sure that the user will not be blocked if the validation is not performed properly.
Conclusion
Form validation does not require complex JavaScript, but it does require thinking carefully about the user. Always remember to help your user to correct the data they provide. To that end, be sure to:
- Display explicit error messages.
- Be permissive about the input format.
- Point out exactly where the error occurs, especially on large forms.
Once you have checked that the form is filled out correctly, the form can be submitted. We'll cover sending form data next.
In this module
- Your first HTML form
- How to structure an HTML form
- The native form widgets
- HTML5 input types
- Additional form controls
- Styling HTML forms
- Form data validation
- Sending form data