Input show error js

I have a HTML5 form with required fields: <input type...

I have the same problem, html5 bubbles do not appear when you capture the on.click event and do something with it, for example to continue with ajax after the html5 validation.

I have observed that if there is any code (a simple alert) in the capture of the click event, it is not shown the validation errors of html5 corresponding to each field (the bubbles)

It is intended that the validation of existing html5 works (that this is not lost and work correctly) and that greater than that can capture the click event and continue doing operations from javascript

HTML5 whith require inputs where bubble must apear!

  <form id='form_insertar' method="post">
  <div class="modal-body">
    <div class="form-group">
      <label for="first_name">First Name</label>
      <input type="text" id="first_name" placeholder="First Name" class="form-control" maxlength="100" required />
    </div>

    <div class="form-group">
      <label for="last_name">Last Name</label>
      <input type="text" id="last_name" placeholder="Last Name" class="form-control" required />
    </div>

    <div class="form-group">
      <label for="email">Email Address</label>
      <input type="text" id="email" placeholder="Email Address" class="form-control" required/>
    </div>      
  </div>
  <div class="modal-footer">
    <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
    <button type="submit" id='btn_addRecord' class="btn btn-primary">Add Record</button>        
  </div>
  </form>

JavaScript code that makes it isn´t appear:

$(document).ready(function(){
    $('#btn_addRecord').on("click", function(event){
        //event.preventDefault();
        if ($("#form_insertar")[0].checkValidity()) {
            console.log('Validado el form: Inserta los datos con ajax!');
              //addRecord();
            return true;
        }
        if (!$("#form_insertar")[0].checkValidity()) {
            console.log('No validado el form: Devolvemos false y no hacemos nada. (LAMENTABLEMENTE HAY ALGO DESCONOCIDO POR LO QUE NO SE MUESTRAN LOS BUBBLES o ERRORES)');    
            return false;
        }
        //alert('test');
    });

});

I have the same problem, html5 bubbles do not appear when you capture the on.click event and do something with it, for example to continue with ajax after the html5 validation.

I have observed that if there is any code (a simple alert) in the capture of the click event, it is not shown the validation errors of html5 corresponding to each field (the bubbles)

It is intended that the validation of existing html5 works (that this is not lost and work correctly) and that greater than that can capture the click event and continue doing operations from javascript

HTML5 whith require inputs where bubble must apear!

  <form id='form_insertar' method="post">
  <div class="modal-body">
    <div class="form-group">
      <label for="first_name">First Name</label>
      <input type="text" id="first_name" placeholder="First Name" class="form-control" maxlength="100" required />
    </div>

    <div class="form-group">
      <label for="last_name">Last Name</label>
      <input type="text" id="last_name" placeholder="Last Name" class="form-control" required />
    </div>

    <div class="form-group">
      <label for="email">Email Address</label>
      <input type="text" id="email" placeholder="Email Address" class="form-control" required/>
    </div>      
  </div>
  <div class="modal-footer">
    <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
    <button type="submit" id='btn_addRecord' class="btn btn-primary">Add Record</button>        
  </div>
  </form>

JavaScript code that makes it isn´t appear:

$(document).ready(function(){
    $('#btn_addRecord').on("click", function(event){
        //event.preventDefault();
        if ($("#form_insertar")[0].checkValidity()) {
            console.log('Validado el form: Inserta los datos con ajax!');
              //addRecord();
            return true;
        }
        if (!$("#form_insertar")[0].checkValidity()) {
            console.log('No validado el form: Devolvemos false y no hacemos nada. (LAMENTABLEMENTE HAY ALGO DESCONOCIDO POR LO QUE NO SE MUESTRAN LOS BUBBLES o ERRORES)');    
            return false;
        }
        //alert('test');
    });

});

  • Previous
  • Overview: Forms
  • Next

Before submitting data to the server, it is important to ensure all required form controls are filled out, in the correct format.
This is called client-side form validation, and 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.

Prerequisites: Computer literacy, a reasonable understanding of
HTML,
CSS, and
JavaScript.
Objective: To understand what client-side form validation is, why it’s important,
and how to apply various techniques to implement it.

Client-side validation is an initial check and an important feature of good user experience; by catching invalid data on the client-side, the user can fix it straight away.
If it gets to the server and is then rejected, a noticeable delay is caused by a round trip to the server and then back to the client-side to tell the user to fix their data.

However, client-side validation should not be considered an exhaustive security measure! Your apps should always perform security checks on any form-submitted data on the server-side as well as the client-side, because client-side validation is too easy to bypass, so malicious users can still easily send bad data through to your server.
Read Website security for an idea of what could happen; implementing server-side validation is somewhat beyond the scope of this module, but you should bear it in mind.

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» (A specific data format is required for it to be considered valid).
  • «Please enter a valid email address» (the data you entered is not in the right format).
  • «Your password needs to be between 8 and 30 characters long and contain one uppercase letter, one symbol, and a number.» (A very specific data format is required for your data).

This is called form validation.
When you enter data, the browser and/or the web server will check to see that the data is in the correct format and within the constraints set by the application. Validation done in the browser is called client-side validation, while validation done on the server is called server-side validation.
In this chapter we are focusing on client-side validation.

If the information is correctly formatted, the 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 user an error message explaining what needs to be corrected, and lets them try again.

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 wrong format, is incorrect, or is omitted altogether.
  • We want to protect our users’ data. 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 client-side validation

There are two different types of client-side validation that you’ll encounter on the web:

  • Built-in form validation uses HTML form validation features, which we’ve discussed in many places throughout this module.
    This validation generally doesn’t require much JavaScript. Built-in form validation has better performance than JavaScript, but it is not as customizable as JavaScript validation.
  • JavaScript validation is coded using JavaScript.
    This validation is completely customizable, but you need to create it all (or use a library).

Using built-in form validation

One of the most significant features of modern form controls is the ability to validate most user data without relying on JavaScript.
This is done by using validation attributes on form elements.
We’ve seen many of these earlier in the course, but to recap:

  • required: Specifies whether a form field needs to be filled in before the form can be submitted.
  • minlength and maxlength: Specifies the minimum and maximum length of textual data (strings).
  • min and max: Specifies the minimum and maximum values of numerical input types.
  • type: Specifies whether the data needs to be a number, an email address, or some other specific preset type.
  • pattern: Specifies a regular expression that defines a pattern the entered data needs to follow.

If the data entered in a form field follows all of the rules specified by the above attributes, 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 (e.g., :out-of-range) 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.

Built-in form validation examples

In this section, we’ll test out some of the attributes that we discussed above.

Simple start file

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 HTML validation feature is the required attribute.
To make an input mandatory, add this attribute to the element.
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 the input is required and invalid. Try out the new behavior in the example below:

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.

The presence of the required attribute on any element that supports this attribute means the element matches the :required pseudo-class whether it has a value or not. If the <input> has no value, the input will match the :invalid pseudo-class.

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?

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 regexps are ideal for form validation and serve a variety of other uses in JavaScript.

Regexps 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 is a (not b, not aa, and so on).
  • abc — Matches a, followed by b, followed by c.
  • ab?c — Matches a, optionally followed by a single b, followed by c. (ac or abc)
  • ab*c — Matches a, optionally followed by any number of bs, followed by c. (ac, abc, abbbbbc, and so on).
  • a|b — Matches one character that is a or b.
  • abc|xyz — Matches exactly abc or exactly xyz (but not abcxyz or a or y, and so on).

There are many more possibilities that we don’t cover here.
For a complete list and many examples, consult our Regular expressions documentation.

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="[Bb]anana|[Cc]herry" />
  <button>Submit</button>
</form>
input:invalid {
  border: 2px dashed red;
}

input:valid {
  border: 2px solid black;
}

This gives us the following update — try it out:

In this example, the <input> element accepts one of four possible values: the strings «banana», «Banana», «cherry», or «Cherry». Regular expressions are case-sensitive, but we’ve made it support capitalized as well as lower-case versions using an extra «Aa» pattern nested inside square brackets.

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 pseudo-class.

Note: Some <input> element types don’t need a pattern attribute to be validated against a regular expression. Specifying the email type, for example, validates the inputs value against a well-formed email address pattern or a pattern matching a comma-separated list of email addresses if it has the multiple 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 if it has a value and that value has fewer characters than the minlength value or more than the maxlength value.

Browsers often don’t let the user type a longer value than expected into text fields. A better user experience than just using maxlength is to also provide character count feedback in an accessible manner and let them edit their content down to size.
An example of this is the character limit seen on Twitter when Tweeting. JavaScript, including solutions using maxlength, can be used to provide this.

Constraining the values of your entries

For number fields (i.e. <input type="number">), the min and max attributes can be used to provide a range of valid values.
If the field contains a value outside this range, it 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 a minlength and maxlength of six, which is the same length as banana and cherry.
  • We’ve also given the number field a min of one and a max 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, the data is invalid.
    The number is not required, so removing the value will still result in a valid value.
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).
In the above example we’ve not included a step attribute, so the value defaults to 1. This means that floats, like 3.2, will also show as invalid.

Full example

Here is a full example to show usage of HTML’s built-in validation features.
First, some HTML:

<form>
  <p>
    <fieldset>
      <legend>Do you have a driver's license?<span aria-label="required">*</span></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?<span aria-label="required">*</span></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 email 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>

And now some CSS to style the HTML:

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;
}

This renders as follows:

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.

Validating forms using JavaScript

You must use JavaScript if you want to take control over the look and feel of native error messages.
In this section we will look at the different ways to do this.

The Constraint Validation API

The Constraint Validation API consists of a set of methods and properties available on the following form element DOM interfaces:

  • HTMLButtonElement (represents a <button> element)
  • HTMLFieldSetElement (represents a <fieldset> element)
  • HTMLInputElement (represents an <input> element)
  • HTMLOutputElement (represents an <output> element)
  • HTMLSelectElement (represents a <select> element)
  • HTMLTextAreaElement (represents a <textarea> element)

The Constraint Validation API makes the following properties available on the above elements.

  • validationMessage: Returns a localized message describing the validation constraints that the control doesn’t satisfy (if any). If the control is not a candidate for constraint validation (willValidate is false) or the element’s value satisfies its constraints (is valid), this will return an empty string.
  • validity: Returns a ValidityState object that contains several properties describing the validity state of the element. You can find full details of all the available properties in the ValidityState reference page; below is listed a few of the more common ones:
    • patternMismatch: Returns true if the value does not match the specified pattern, and false if it does match. If true, the element matches the :invalid CSS pseudo-class.
    • tooLong: Returns true if the value is longer than the maximum length specified by the maxlength attribute, or false if it is shorter than or equal to the maximum. If true, the element matches the :invalid CSS pseudo-class.
    • tooShort: Returns true if the value is shorter than the minimum length specified by the minlength attribute, or false if it is greater than or equal to the minimum. If true, the element matches the :invalid CSS pseudo-class.
    • rangeOverflow: Returns true if the value is greater than the maximum specified by the max attribute, or false if it is less than or equal to the maximum. If true, the element matches the :invalid and :out-of-range CSS pseudo-classes.
    • rangeUnderflow: Returns true if the value is less than the minimum specified by the min attribute, or false if it is greater than or equal to the minimum. If true, the element matches the :invalid and :out-of-range CSS pseudo-classes.
    • typeMismatch: Returns true if the value is not in the required syntax (when type is email or url), or false if the syntax is correct. If true, the element matches the :invalid CSS pseudo-class.
    • valid: Returns true if the element meets all its validation constraints, and is therefore considered to be valid, or false if it fails any constraint. If true, the element matches the :valid CSS pseudo-class; the :invalid CSS pseudo-class otherwise.
    • valueMissing: Returns true if the element has a required attribute, but no value, or false otherwise. If true, the element matches the :invalid CSS pseudo-class.
  • willValidate: Returns true if the element will be validated when the form is submitted; false otherwise.

The Constraint Validation API also makes the following methods available on the above elements and the form element.

  • checkValidity(): Returns true if the element’s value has no validity problems; false otherwise. If the element is invalid, this method also fires an invalid event on the element.
  • reportValidity(): Reports invalid field(s) using events. This method is useful in combination with preventDefault() in an onSubmit event handler.
  • 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 HTML validation constraints. The message is shown to the user when reporting the problem.

Implementing a customized error message

As you saw in the HTML validation constraint examples earlier, 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, as seen in the following Firefox screenshot.

Example of an error message with Firefox in French on an English page

Customizing these error messages is one of the most common use cases of the Constraint Validation API.
Let’s work through a simple example of how to do this.

We’ll start with some simple HTML (feel free to put this in a blank HTML file; use a fresh copy of fruit-start.html as a basis, if you like):

<form>
  <label for="mail">
    I would like you to provide me with an email address:
  </label>
  <input type="email" id="mail" name="mail" />
  <button>Submit</button>
</form>

And add the following JavaScript to the page:

const email = document.getElementById("mail");

email.addEventListener("input", (event) => {
  if (email.validity.typeMismatch) {
    email.setCustomValidity("I am expecting an email address!");
  } else {
    email.setCustomValidity("");
  }
});

Here we store a reference to the email input, then add an event listener to it that runs the contained code each time the value inside the input is changed.

Inside the contained code, we check whether the email input’s validity.typeMismatch property returns true, meaning that the contained value doesn’t match the pattern for a well-formed email address. If so, we call the setCustomValidity() method with a custom message. This renders the input invalid, so that when you try to submit the form, submission fails and the custom error message is displayed.

If the validity.typeMismatch property returns false, we call the setCustomValidity() method with an empty string. This renders the input valid, so the form will submit.

You can try it out below:

A more detailed example

Now that we’ve seen a really simple example, let’s see how we can use this API to build some slightly more complex custom validation.

First, the HTML. Again, feel free to build this along with us:

<form novalidate>
  <p>
    <label for="mail">
      <span>Please enter an email address:</span>
      <input type="email" id="mail" name="mail" required minlength="8" />
      <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 CSS pseudo-classes like :valid, etc.
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.

Our input to validate is an <input type="email">, which is required, and has a minlength of 8 characters. Let’s check these using our own code, and show a custom error message for each one.

We are aiming to show the error messages inside a <span> element.
The aria-live attribute is set on that <span> to make sure that our custom error message will be presented to everyone, including it being read out to screen reader users.

Note: A key point here is that setting the novalidate attribute on the form is what stops the form from showing its own error message bubbles, and allows us to instead display the custom error messages in the DOM in some manner of our own choosing.

Now onto some basic CSS to improve the look of the form slightly, and provide some visual feedback when the input data is invalid:

body {
  font: 1em sans-serif;
  width: 200px;
  padding: 0;
  margin: 0 auto;
}

p * {
  display: block;
}

input[type="email"] {
  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;
}

Now let’s look at the JavaScript that implements 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.querySelector("form");
const email = document.getElementById("mail");
const emailError = document.querySelector("#mail + span.error");

email.addEventListener("input", (event) => {
  // Each time the user types something, we check if the
  // form fields are valid.

  if (email.validity.valid) {
    // In case there is an error message visible, if the field
    // is valid, we remove the error message.
    emailError.textContent = ""; // Reset the content of the message
    emailError.className = "error"; // Reset the visual state of the message
  } else {
    // If there is still an error, show the correct error
    showError();
  }
});

form.addEventListener("submit", (event) => {
  // if the email field is valid, we let the form submit
  if (!email.validity.valid) {
    // If it isn't, we display an appropriate error message
    showError();
    // Then we prevent the form from being sent by canceling the event
    event.preventDefault();
  }
});

function showError() {
  if (email.validity.valueMissing) {
    // If the field is empty,
    // display the following error message.
    emailError.textContent = "You need to enter an email address.";
  } else if (email.validity.typeMismatch) {
    // If the field doesn't contain an email address,
    // display the following error message.
    emailError.textContent = "Entered value needs to be an email address.";
  } else if (email.validity.tooShort) {
    // If the data is too short,
    // display the following error message.
    emailError.textContent = `Email should be at least ${email.minLength} characters; you entered ${email.value.length}.`;
  }

  // Set the styling appropriately
  emailError.className = "error active";
}

The comments explain things pretty well, but briefly:

  • Every time we change the value of the input, we check to see if it contains valid data.
    If it has then we remove any error message being shown.
    If the data is not valid, we run showError() to show the appropriate error.
  • Every time we try to submit the form, we again check to see if the data is valid. If so, we let the form submit.
    If not, we run showError() to show the appropriate error, and stop the form submitting with preventDefault().
  • The showError() function uses various properties of the input’s validity object to determine what the error is, and then displays an error message as appropriate.

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

In some cases, such as custom controls, you won’t be able to or won’t want to use the Constraint Validation API. You’re still able to use JavaScript to validate your form, but you’ll just have to write your own.

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.

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, here are some useful articles you should read:

  • Help users enter the right data in forms
  • Validating input
  • How to Report Errors in Forms: 10 Design Guidelines

An example that doesn’t use the constraint validation API

In order to illustrate this, the following is a simplified version of the previous example without the Constraint Validation API.

The HTML is almost the same; we just removed the HTML validation features.

<form>
  <p>
    <label for="mail">
      <span>Please enter an email address:</span>
      <input type="text" id="mail" name="mail" />
      <span class="error" aria-live="polite"></span>
    </label>
  </p>
  <button>Submit</button>
</form>

Similarly, the CSS doesn’t need to change very much; we’ve just turned the :invalid CSS pseudo-class into a real class and avoided using the attribute selector that doesn’t work on Internet Explorer 6.

body {
  font: 1em sans-serif;
  width: 200px;
  padding: 0;
  margin: 0 auto;
}

form {
  max-width: 200px;
}

p * {
  display: block;
}

input.mail {
  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;
}

The big changes are in the JavaScript code, which needs to do much more heavy lifting.

const form = document.querySelector("form");
const email = document.getElementById("mail");
const error = email.nextElementSibling;

// As per the HTML Specification
const emailRegExp =
  /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:.[a-zA-Z0-9-]+)*$/;

// 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
window.addEventListener("load", () => {
  // 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 email address.
  const isValid = email.value.length === 0 || emailRegExp.test(email.value);
  email.className = isValid ? "valid" : "invalid";
});

// This defines what happens when the user types in the field
email.addEventListener("input", () => {
  const isValid = email.value.length === 0 || emailRegExp.test(email.value);
  if (isValid) {
    email.className = "valid";
    error.textContent = "";
    error.className = "error";
  } else {
    email.className = "invalid";
  }
});

// This defines what happens when the user tries to submit the data
form.addEventListener("submit", (event) => {
  event.preventDefault();

  const isValid = email.value.length === 0 || emailRegExp.test(email.value);
  if (!isValid) {
    email.className = "invalid";
    error.textContent = "I expect an email, darling!";
    error.className = "error active";
  } else {
    email.className = "valid";
    error.textContent = "";
    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 both cross-platform and on any form you might create. There are many libraries available to perform form validation, such as Validate.js.

Test your skills!

You’ve reached the end of this article, but can you remember the most important information? You can find some further tests to verify that you’ve retained this information before you move on — see Test your skills: Form validation.

Summary

Client-side form validation sometimes requires JavaScript if you want to customize styling and error messages, but it always requires you to think carefully about the user.
Always remember to help your users 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.

  • Previous
  • Overview: Forms
  • Next

In this module

Advanced Topics

Summary: in this tutorial, you’ll learn about JavaScript form validation by building a signup form from scratch.

What is form validation

Before submitting data to the server, you should check the data in the web browser to ensure that the submitted data is in the correct format.

To provide quick feedback, you can use JavaScript to validate data. This is called client-side validation.

If you don’t carry the client-side validation, it may cause a bad user experience. In this case, you may feel a noticeable delay because it takes time for the form data to transfer between the web browsers and the server.

Unlike the client-side validation that performs in the web browser, the server-side validation is performed on the server. It’s critical always to implement the server-side validation.

The reason is that client-side validation is quite easy to bypass. Malicious users can disable JavaScript and submit bad data to your server.

In this tutorial, you’re going to focus on the client-side validation only.

Client-side validation options

When it comes to client-side validation, you’ll have two options:

  • JavaScript validation: you develop the validation logic using JavaScript. Or you can use a library to do so.
  • Built-in form validation: you can use the HTML5 form validation features. This validation has a better performance than JavaScript validation. However, it isn’t as customizable as JavaScript validation.

You will create a simple signup form with four input fields: username, email, password, and confirm password.

When you click the sign up without filling anything or filling incorrect data format, the form will show error messages:

You’ll validate the following:

  • Username cannot be blank and has at least 3 characters and cannot be longer than 25 characters.
  • Email is mandatory and valid.
  • Password has eight characters or longer. And it must contain 1 lowercase character, 1 uppercase character, 1 number, and at least one special character in this set (!@#$%^&*).
  • The confirm password must be the same as the password.

Create the project structure

First, create the form-validation folder that stores all the source code files of the project.

Second, create the js and css folders inside the form-validation folder.

Third, create the style.css in the css folder, the app.js in the js folder, and index.html directly in the form-validation folder.

The final project structure will look like this:

Build the HTML form

First, open the index.html file and enter the following code:

<!DOCTYPE html> <html> <head> <title>JavaScript Form Validation Demo</title> <link rel="stylesheet" href="css/style.css"> </head> <body> <script src="js/app.js"></script> </body> </html>

Code language: HTML, XML (xml)

In this HTML file, we place the style.css file in the head section and app.js file in the body section before the closing </body> tag.

Second, add the following HTML markup to create the signup form. The final index.html file will look like the following:

<!DOCTYPE html> <html> <head> <title>JavaScript Form Validation Demo</title> <link rel="stylesheet" href="css/style.css"> </head> <body> <div class="container"> <form id="signup" class="form"> <h1>Sign Up</h1> <div class="form-field"> <label for="username">Username:</label> <input type="text" name="username" id="username" autocomplete="off"> <small></small> </div> <div class="form-field"> <label for="email">Email:</label> <input type="text" name="email" id="email" autocomplete="off"> <small></small> </div> <div class="form-field"> <label for="password">Password:</label> <input type="password" name="password" id="password" autocomplete="off"> <small></small> </div> <div class="form-field"> <label for="confirm-password">Confirm Password:</label> <input type="password" name="confirm-password" id="confirm-password" autocomplete="off"> <small></small> </div> <div class="form-field"> <input type="submit" value="Sign Up"> </div> </form> </div> <script src="js/app.js"></script> </body> </html>

Code language: HTML, XML (xml)

The notable thing about the signup form is that each field is wrapped in a div with the class form-field.

Each form field has three elements:

  • A label
  • An input field
  • A <small> element

You’ll use the <small> tag to show the error message to the users.

If an input field isn’t valid, we’ll make its border color red by adding the error class to the form-field element. It’ll look like this:

<div class="form-field error"> <label for="username">Username:</label> <input type="text" name="username" id="username" autocomplete="off"> <small></small> </div>

Code language: JavaScript (javascript)

If the value of an input field is valid, then we’ll make its border color green by adding the success class to the form-field element as follows:

<div class="form-field success"> <label for="username">Username:</label> <input type="text" name="username" id="username" autocomplete="off"> <small></small> </div>

Code language: JavaScript (javascript)

Check out the style.css for details of the.error and .success classes.

Select the form fields and add the submit event listener

In the app.js file, you’ll first use the document.querySelector() method to select the input fields and the form:

const usernameEl = document.querySelector('#username'); const emailEl = document.querySelector('#email'); const passwordEl = document.querySelector('#password'); const confirmPasswordEl = document.querySelector('#confirm-password'); const form = document.querySelector('#signup');

Code language: JavaScript (javascript)

And then you attach the submit event listener to the form by using the addEventListener() method:

form.addEventListener('submit', function (e) { // prevent the form from submitting e.preventDefault(); });

Code language: JavaScript (javascript)

In the event listener, you need to call the e.preventDefault() to prevent the form from submitting once the submit button is clicked.

Develop utility functions

Before validating the form, you can develop some reusable utility functions to check if:

  • A field is required.
  • The length of a field is between min and max.
  • The email is in a valid format.
  • The password is strong.

The following isRequired() function returns true if the input argument is empty:

const isRequired = value => value === '' ? false : true;

Code language: JavaScript (javascript)

The following isBetween() function returns false if the length argument is not between the min and max argument:

const isBetween = (length, min, max) => length < min || length > max ? false : true;

Code language: JavaScript (javascript)

To check the email is valid, you’ll use a regular expression:

const isEmailValid = (email) => { const re = /^(([^<>()[]\.,;:s@"]+(.[^<>()[]\.,;:s@"]+)*)|(".+"))@(([[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}])|(([a-zA-Z-0-9]+.)+[a-zA-Z]{2,}))$/; return re.test(email); };

Code language: JavaScript (javascript)

To check if a password is strong, which match a specified pattern, you’ll also use a regular expression:

const isPasswordSecure = (password) => { const re = new RegExp("^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#$%^&*])(?=.{8,})"); return re.test(password); };

Code language: JavaScript (javascript)

The following table illustrates the meaning of each part of the regular expression used to validate the password:

Password RegEx Meaning
^ The password starts
(?=.*[a-z]) The password must contain at least one lowercase character
(?=.*[A-Z]) The password must contain at least one uppercase character
(?=.*[0-9]) The password must contain at least one number
(?=.*[!@#$%^&*]) The password must contain at least one special character.
(?=.{8,}) The password must be eight characters or longer

Develop functions that show the error / success

The following showError() function highlights the border of the input field and displays an error message if the input field is invalid:

const showError = (input, message) => { // get the form-field element const formField = input.parentElement; // add the error class formField.classList.remove('success'); formField.classList.add('error'); // show the error message const error = formField.querySelector('small'); error.textContent = message; };

Code language: JavaScript (javascript)

How it works.

First, get the parent element of the input field, which is the <div> element that contains the form-field class:

const formField = input.parentElement;

Code language: JavaScript (javascript)

Second, remove the success class and add the error class to the form-field element:

formField.classList.remove('success'); formField.classList.add('error');

Code language: JavaScript (javascript)

Third, select the <small> element inside the form-field element:

const error = formField.querySelector('small');

Code language: JavaScript (javascript)

Notice that you use the formField.querySelector() instead of the document.querySelector().

Finally, set the error message to its textContent property of the <small> element:

error.textContent = message;

The function that shows the success indicator is similar to the showError() function:

const showSuccess = (input) => { // get the form-field element const formField = input.parentElement; // remove the error class formField.classList.remove('error'); formField.classList.add('success'); // hide the error message const error = formField.querySelector('small'); error.textContent = ''; }

Code language: JavaScript (javascript)

Unlike the showError() function, the showSuccess() function removes the error class, adds the success class, and set the error message to blank.

Now, you can use the utility function above to check for each field.

Develop input field validating functions

You’ll develop four functions for validating values of the form fields:

1) Validate the username field

The following checkUsername() function uses:

  • The isRequired() function to check if the username is provided.
  • The isBetween() function to check if the length of the username is between 3 and 25 characters.
  • The showError() and showSuccess() functions to show the error and success indicator.

The function returns true if the field passes the checks.

const checkUsername = () => { let valid = false; const min = 3, max = 25; const username = usernameEl.value.trim(); if (!isRequired(username)) { showError(usernameEl, 'Username cannot be blank.'); } else if (!isBetween(username.length, min, max)) { showError(usernameEl, `Username must be between ${min} and ${max} characters.`) } else { showSuccess(usernameEl); valid = true; } return valid; }

Code language: JavaScript (javascript)

2) Validate the email field

The checkEmail() function returns true if the email is provided and valid.

It uses the isRequired() and isEmailValid() functions for checking. And it uses the showError() and showSuccess() functions to provide feedback in case of error and success.

const checkEmail = () => { let valid = false; const email = emailEl.value.trim(); if (!isRequired(email)) { showError(emailEl, 'Email cannot be blank.'); } else if (!isEmailValid(email)) { showError(emailEl, 'Email is not valid.') } else { showSuccess(emailEl); valid = true; } return valid; }

Code language: JavaScript (javascript)

3) Validate the password field

The following checkPassword() function checks the password field if it is provided and match the required format:

const checkPassword = () => { let valid = false; const password = passwordEl.value.trim(); if (!isRequired(password)) { showError(passwordEl, 'Password cannot be blank.'); } else if (!isPasswordSecure(password)) { showError(passwordEl, 'Password must has at least 8 characters that include at least 1 lowercase character, 1 uppercase characters, 1 number, and 1 special character in (!@#$%^&*)'); } else { showSuccess(passwordEl); valid = true; } return valid; };

Code language: JavaScript (javascript)

4) Validate the confirm password field

The checkConfirmPassword() function checks if the confirm password is the same as the password.

const checkConfirmPassword = () => { let valid = false; // check confirm password const confirmPassword = confirmPasswordEl.value.trim(); const password = passwordEl.value.trim(); if (!isRequired(confirmPassword)) { showError(confirmPasswordEl, 'Please enter the password again'); } else if (password !== confirmPassword) { showError(confirmPasswordEl, 'Confirm password does not match'); } else { showSuccess(confirmPasswordEl); valid = true; } return valid; };

Code language: JavaScript (javascript)

Modifying the submit event handler

Now, you can use the functions that validate the input fields in the submit event handler:

form.addEventListener('submit', function (e) { // prevent the form from submitting e.preventDefault(); // validate forms let isUsernameValid = checkUsername(), isEmailValid = checkEmail(), isPasswordValid = checkPassword(), isConfirmPasswordValid = checkConfirmPassword(); let isFormValid = isUsernameValid && isEmailValid && isPasswordValid && isConfirmPasswordValid; // submit to the server if the form is valid if (isFormValid) { } });

Code language: JavaScript (javascript)

How it works:

  • First, call each individual function to validate username, email, password, and confirm password fields.
  • Second, use the && operator to determine if the form is valid. The form is valid only if all fields are valid.
  • Finally, submit data to the server if the form is valid specified the isFormValid flag. Note that submitting form data to the server isn’t covered in this tutorial.

Now, you can open the index.html file, enter some values and click the submit button to test it.

Add Instant feedback feature

The form only shows the error or success when you click the Sign Up button.

To provide instant feedback, you can attach an event listener to the input event of each field and validate it.

It’s even better to use the event delegation so that you attach the input event listener to the form and validate each field based on the current field id, like this:

form.addEventListener('input', function (e) { switch (e.target.id) { case 'username': checkUsername(); break; case 'email': checkEmail(); break; case 'password': checkPassword(); break; case 'confirm-password': checkConfirmPassword(); break; } });

Code language: JavaScript (javascript)

If you open the index.html and enter some data, you’ll see that the form shows the feedback either error or success instantly.

Also, you improve the performance of the form by using the debouncing technique.

Technically, you’ll wait for the users to pause the typing for a small amount of time or stop typing before validating the input.

For the detail of the debouncing technique, check it out in this tutorial.

The following illustrates the debounce() function:

const debounce = (fn, delay = 500) => { let timeoutId; return (...args) => { // cancel the previous timer if (timeoutId) { clearTimeout(timeoutId); } // setup a new timer timeoutId = setTimeout(() => { fn.apply(null, args) }, delay); }; };

Code language: JavaScript (javascript)

Now, you can pass the input event handler to the debounce() function to debounce it:

form.addEventListener('input', debounce(function (e) { switch (e.target.id) { case 'username': checkUsername(); break; case 'email': checkEmail(); break; case 'password': checkPassword(); break; case 'confirm-password': checkConfirmPassword(); break; } }));

Code language: JavaScript (javascript)

If you enter data to a form field to trigger the input event, you’ll see that the error or success message will have a bit of delay.

The following shows the complete app.js file:

const usernameEl = document.querySelector('#username'); const emailEl = document.querySelector('#email'); const passwordEl = document.querySelector('#password'); const confirmPasswordEl = document.querySelector('#confirm-password'); const form = document.querySelector('#signup'); const checkUsername = () => { let valid = false; const min = 3, max = 25; const username = usernameEl.value.trim(); if (!isRequired(username)) { showError(usernameEl, 'Username cannot be blank.'); } else if (!isBetween(username.length, min, max)) { showError(usernameEl, `Username must be between ${min} and ${max} characters.`) } else { showSuccess(usernameEl); valid = true; } return valid; }; const checkEmail = () => { let valid = false; const email = emailEl.value.trim(); if (!isRequired(email)) { showError(emailEl, 'Email cannot be blank.'); } else if (!isEmailValid(email)) { showError(emailEl, 'Email is not valid.') } else { showSuccess(emailEl); valid = true; } return valid; }; const checkPassword = () => { let valid = false; const password = passwordEl.value.trim(); if (!isRequired(password)) { showError(passwordEl, 'Password cannot be blank.'); } else if (!isPasswordSecure(password)) { showError(passwordEl, 'Password must has at least 8 characters that include at least 1 lowercase character, 1 uppercase characters, 1 number, and 1 special character in (!@#$%^&*)'); } else { showSuccess(passwordEl); valid = true; } return valid; }; const checkConfirmPassword = () => { let valid = false; // check confirm password const confirmPassword = confirmPasswordEl.value.trim(); const password = passwordEl.value.trim(); if (!isRequired(confirmPassword)) { showError(confirmPasswordEl, 'Please enter the password again'); } else if (password !== confirmPassword) { showError(confirmPasswordEl, 'The password does not match'); } else { showSuccess(confirmPasswordEl); valid = true; } return valid; }; const isEmailValid = (email) => { const re = /^(([^<>()[]\.,;:s@"]+(.[^<>()[]\.,;:s@"]+)*)|(".+"))@(([[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}])|(([a-zA-Z-0-9]+.)+[a-zA-Z]{2,}))$/; return re.test(email); }; const isPasswordSecure = (password) => { const re = new RegExp("^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#$%^&*])(?=.{8,})"); return re.test(password); }; const isRequired = value => value === '' ? false : true; const isBetween = (length, min, max) => length < min || length > max ? false : true; const showError = (input, message) => { // get the form-field element const formField = input.parentElement; // add the error class formField.classList.remove('success'); formField.classList.add('error'); // show the error message const error = formField.querySelector('small'); error.textContent = message; }; const showSuccess = (input) => { // get the form-field element const formField = input.parentElement; // remove the error class formField.classList.remove('error'); formField.classList.add('success'); // hide the error message const error = formField.querySelector('small'); error.textContent = ''; } form.addEventListener('submit', function (e) { // prevent the form from submitting e.preventDefault(); // validate fields let isUsernameValid = checkUsername(), isEmailValid = checkEmail(), isPasswordValid = checkPassword(), isConfirmPasswordValid = checkConfirmPassword(); let isFormValid = isUsernameValid && isEmailValid && isPasswordValid && isConfirmPasswordValid; // submit to the server if the form is valid if (isFormValid) { } }); const debounce = (fn, delay = 500) => { let timeoutId; return (...args) => { // cancel the previous timer if (timeoutId) { clearTimeout(timeoutId); } // setup a new timer timeoutId = setTimeout(() => { fn.apply(null, args) }, delay); }; }; form.addEventListener('input', debounce(function (e) { switch (e.target.id) { case 'username': checkUsername(); break; case 'email': checkEmail(); break; case 'password': checkPassword(); break; case 'confirm-password': checkConfirmPassword(); break; } }));

Code language: JavaScript (javascript)

And here is the final form.

Summary

  • What client-side validation is and the difference between the client-side vs. server-side validation.
  • How to compose a form and combine JavaScript and CSS to validate input fields.
  • How to use regular expressions to check if field values are in the correct format.
  • How to use the event delegation technique.
  • How to use the debouncing technique to improve the performance for the form validation.

Was this tutorial helpful ?

Updated: 22-Aug-2022 | Tags: HTML, CSS and Javascript | Views: 2435

Introduction

In this tutorial we are going to see how to display form errors under every input field with javascript.
In the example below we have a register form, and we are going to validate every field to check its value.
If the field is empty we are going to show an error message under the empty field.
Click on the submit button and try it out.

Ok, now let’s see how we do this.

By the way you can download the source code of the demo if you scroll at the end of the page.

Files we need

We create two files in the same folder.

  • An index.php file in which we are going to write the html code.
  • And a script.js file to write the javascript code.
  • If you download the source code you will get also the stylesheet.

The html code

Below we have the form element its the same form that you tried out in the demo above.
Let quick see what we have here.

<form name="register-form" action="" method="post">
	<label>Enter Username</label>
	<input type="text" name="username">
	<p class="error username-error"></p>
	
	<label>Enter Password</label>
	<input type="text" name="password">
	<p class="error password-error"></p>

	<label>Enter email</label>
	<input type="text" name="email">
	<p class="error email-error"></p>
	
	<button type="submit" name="submit">Submit</button>

	<p class="success"></p>			
</form>

<script src="script.js"></script>
  • In line 1 we gave the form a name by setting the name’s attribute value to «register-form».
    We are gonna use the name attribute in the javascript code to target the form.
  • In line 3 we have the username input field, and under it in line 4 we have a p tag that acts as a placeholder.
    We gave the paragraph element a generic class of «error» to give every error element the same style.
    But we gave it also a unique class of «username-error» so we can target it from the javascript file and display the message.
    The error element is hidden by default in the css file, setting the display property to «hidden».
    We are going to change the display property to «block» in the javascript code if an error occurs.
    We will see that when we get to the javascript section.
  • We do the exact same thing in line 7-8 with the password field,
    and in line 11-12 with the email input field.
  • In line 14 we have the submit button.
  • In line 16 we have a p tag to display the success message.
  • And in line 19 we have a script tag pointing to the javascript file.

Now let’s go write the javascript code.

The JavaScript code

In the javascript file i will target the register form and add an onsubmit event-listener. So every time we click on the submit
button a function will run. I will pass in the function as an argument the event object, because i need the preventDefault() method to stop the form
submit the data to the server if an error occurs.

document.forms['register-form'].onsubmit = function(event){
	
	if(this.username.value.trim() === ""){
		document.querySelector(".username-error").innerHTML = "Please enter a username";
		document.querySelector(".username-error").style.display = "block";
		event.preventDefault();
		return false;
	}

	if(this.password.value.trim() === ""){
		document.querySelector(".password-error").innerHTML = "Please enter a password";
		document.querySelector(".password-error").style.display = "block";
		event.preventDefault();
		return false;
	}

	if(this.email.value.trim() === ""){
		document.querySelector(".email-error").innerHTML = "Please enter a email";
		document.querySelector(".email-error").style.display = "block";
		event.preventDefault();
		return false;
	}

}	

Explaining the logic

  • In the first if statement i will target the username input field and get the value, this.username.value.

    	if(this.username.value.trim() === ""){
    		document.querySelector(".username-error").innerHTML = "Please enter a username";
    		document.querySelector(".username-error").style.display = "block";
    		event.preventDefault();
    		return false;
    	}
    		

    In line 3 i have an if statement to check if the username input field is empty. I also use the trim() method because
    if we type just spaces in the field this is considered as not empty. Space is considered as a value.

    If the condition returns true, that means that the input field is empty so in line 4 we are targeting the «username-error» placeholder
    and with the innerHTML property we show the user a message. We also have to change the display property to block
    in line 5 to make the element visible.
    Remember that i mentioned that the error elements are set to display: none in the css file.
    In line 6 we use the preventDefault() method to stop the form to send the data to the server.
    And in line 7 we return false to stop the function.

  • The same concept is applied to the other two input fields.

And that’s it, this is how to display error message in html form with javascript.
I hope you like it.

Source code

Thanks for reading, i hope you find the article helpful.
Please leave a comment if you find any errors, so i can update the page with the correct code.

You can download the source code and use it in any way you like.

Times downloaded: 241

If you feel like saying thanks, you can buy me a coffee

Related Articles

Comment section

Search for a tutorial

Tutorial Categories

Basic php stuff

Basic JavaScript stuff

Basic HTML and CSS stuff

Cover image for Form validation using javascript

Adam Nagy

Adam Nagy

Posted on Oct 31, 2021

• Updated on Nov 4, 2021

Working with forms is an every day task for almost every web developer. No matter what site you’ll create it will use forms. Validating the form data on the client side is a nice-to-have feature when it comes to user experience. In this tutorial we’ll create a simple form validation using javascript.

While client-side form validation gives a nice user experience, it can be tricked and bypassed really easily. To prevent malicious use, you should always validate form data on the server side

Video Tutorial

If you would watch a detailed step-by-step video instead you can check out the video I made covering this project on my Youtube Channel:

HTML

Let’s start with the HTML markup. We’ll have a container div, that we’ll use to position and style our form. Inside that, not surprisingly, we’ll create a form, we also set an id for it, and set the action to / since we don’t really want to submit this form.

We’ll create four input fields, for the username, email, password, and password confirmation. For styling and control purposes we’ll wrap these input tags into divs with the class input control. Each of these input controls will contain a label, an input, and a div with the class error. Every input should have an id and name attribute. The label’s should have a matching for property with the corresponding input tag’s name attribute. For the input type we will use text for the username and email, and use password for the password and the password confirmation. The div with the error class will hold the error messages for the specific input field. It will be empty for now, we will modify it from javascript.

Lastly, we have to add a button to «submit» our form. In this example we won’t really submit the form just simulate it. For the submit button I’ll use a button with a type of submit.

<div class="container">
        <form id="form" action="/">
            <h1>Registration</h1>
            <div class="input-control">
                <label for="username">Username</label>
                <input id="username" name="username" type="text">
                <div class="error"></div>
            </div>
            <div class="input-control">
                <label for="email">Email</label>
                <input id="email" name="email" type="text">
                <div class="error"></div>
            </div>
            <div class="input-control">
                <label for="password">Password</label>
                <input id="password"name="password" type="password">
                <div class="error"></div>
            </div>
            <div class="input-control">
                <label for="password2">Password again</label>
                <input id="password2"name="password2" type="password">
                <div class="error"></div>
            </div>
            <button type="submit">Sign Up</button>
        </form>
    </div>

Enter fullscreen mode

Exit fullscreen mode

That is the HTML markup that we need for our form. Let’s style it a bit with CSS.

CSS

We’ll give a simple clean spacious design for this tutorial. I’ll set a linear gradient as the background and I’ll use a custom google font, that you can install from here.

body {
    background: linear-gradient(to right, #0f2027, #203a43, #2c5364);
    font-family: 'Poppins', sans-serif;
}

Enter fullscreen mode

Exit fullscreen mode

We’ll give a fix width to our form, and center it with margins, also I’ll give it a top margin to move it down a bit vertically. To have more space we apply 20px of padding. We’ll set a fixed font size, a light background color and also set a border radius to have rounded corners.

#form {
    width: 300px;
    margin: 20vh auto 0 auto;
    padding: 20px;
    background-color: whitesmoke;
    border-radius: 4px;
    font-size: 12px;
}

Enter fullscreen mode

Exit fullscreen mode

For the form title, we’ll use a dark text color, and center it horizontally using text-align: center. The submit button should stand out so we’ll use a blue background color, and white text color. We also remove the browser default borders and give it a little border-radius. We’ll give it a little spacing with paddings and margins, and make it full-width by applying 100% width.

#form h1 {
    color: #0f2027;
    text-align: center;
}

#form button {
    padding: 10px;
    margin-top: 10px;
    width: 100%;
    color: white;
    background-color: rgb(41, 57, 194);
    border: none;
    border-radius: 4px;
}

Enter fullscreen mode

Exit fullscreen mode

To have the inputs stacked below each other we’ll use flexbox. To do that we’ll set display: flex; and flex-direction: column. For the inputs we’ll set a grey border, with a little border-radius. We’ll set the display property to block, and make them full-width, by applying width 100%. We’ll also set a little padding, so it’ll be more spacious. I’ll also remove the outline when the input is in focus, by setting outline: 0.

.input-control {
    display: flex;
    flex-direction: column;
}

.input-control input {
    border: 2px solid #f0f0f0;
    border-radius: 4px;
    display: block;
    font-size: 12px;
    padding: 10px;
    width: 100%;
}

.input-control input:focus {
    outline: 0;
}

Enter fullscreen mode

Exit fullscreen mode

We’ll use two classes («success» and «error») to give visual feedback to the user on whether the input’s value is valid or not. We’ll apply these classes from javascript to the input-control div which contains the specific input field. When the success class is present we will set a green border color, otherwise if error is present we’ll use a red border color instead. For the error div we’ll use a smaller font-size and a red color to show the error messages.

.input-control.success input {
    border-color: #09c372;
}

.input-control.error input {
    border-color: #ff3860;
}

.input-control .error {
    color: #ff3860;
    font-size: 9px;
    height: 13px;
}

Enter fullscreen mode

Exit fullscreen mode

Let’s do the validation in javascript next!

Javascript

The first thing we have to do is to save references for the form, and the input fields. As we gave id for every input and the form we can easily to do by using getElementById.

const form = document.getElementById('form');
const username = document.getElementById('username');
const email = document.getElementById('email');
const password = document.getElementById('password');
const password2 = document.getElementById('password2');

Enter fullscreen mode

Exit fullscreen mode

To prevent the form for automatically submit we have to attach and event listener to our form’s submit event. In this event handler function we have to call preventDefault() function to prevent the form from submitting automatically. Instead of submitting we’ll call the validateInputs function, which will validate the inputs and if we want to we can submit the form in there after every check passes, but we won’t do that in this tutorial. We’ll create this validateInputs shortly.

form.addEventListener('submit', e => {
    e.preventDefault();

    validateInputs();
});

Enter fullscreen mode

Exit fullscreen mode

We’ll also create two helper functions: setErrorsetSuccess. We’ll use these helper functions to set the error or success states of the input controls. Let’s start with the setError one. It receives two parameters: element, and message. The element will be the input element that is in the specific input-control. So first we have to get the input control parent div. We’ll save it into the inputControl variable, and get the input control div by using the parent property of the input element. Next we have to gather the error div, and save it into a variable. We can do that by querying the input control with the error class.
Now we have to set the error div’s innerText to be the message that we got in parameters, and remove the success class from the input control (if it exists) and add the error class.

const setError = (element, message) => {
    const inputControl = element.parentElement;
    const errorDisplay = inputControl.querySelector('.error');

    errorDisplay.innerText = message;
    inputControl.classList.add('error');
    inputControl.classList.remove('success')
}

Enter fullscreen mode

Exit fullscreen mode

The setSuccess method will be really similar. The first difference is that it won’t receive a message as a parameter. We have to clear the error display by setting its innerText to an empty string. Lastly we have to reverse the class application. We’ll add the success class to the inputControl and remove the error class (if present).

const setSuccess = element => {
    const inputControl = element.parentElement;
    const errorDisplay = inputControl.querySelector('.error');

    errorDisplay.innerText = '';
    inputControl.classList.add('success');
    inputControl.classList.remove('error');
};

Enter fullscreen mode

Exit fullscreen mode

We will create one last helper function to validate emails. This is an optional step, if you don’t want to use regular expressions, feel free to just set the input type of the email field to email. The isValidEmail function will take a string as a parameter and use this weird looking regular expression to check whether it is a valid email or not. We’ll use String.test() function to test the string against the regex. We’ll also convert the email to a string and make it lowercase.

const isValidEmail = email => {
    const re = /^(([^<>()[]\.,;:s@"]+(.[^<>()[]\.,;:s@"]+)*)|(".+"))@(([[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}])|(([a-zA-Z-0-9]+.)+[a-zA-Z]{2,}))$/;
    return re.test(String(email).toLowerCase());
}

Enter fullscreen mode

Exit fullscreen mode

Now we should create the validator validateInputs function. First we will get the value of all the input fields. We can do that by getting the value property’s value of the input field references. We’ll call the String.trim() function to remove the trailing empty spaces (if any) from the start and end of the values.
Then we can start validating inputs. We’ll use if, else statements to do the validation. For the username we will check whether if it is empty or not, by comparing the value with an empty string. If it empty, we’ll call the setError function and provide the username element to it, with our error message. Otherwise we’ll call the setSuccess method with the username element. Now we have to do this for the other input fields, but the approach will be the same.

const validateInputs = () => {
    const usernameValue = username.value.trim();
    const emailValue = email.value.trim();
    const passwordValue = password.value.trim();
    const password2Value = password2.value.trim();

    if(usernameValue === '') {
        setError(username, 'Username is required');
    } else {
        setSuccess(username);
    }
};

Enter fullscreen mode

Exit fullscreen mode

For the email we’ll check if it is provided or not, and set an error if it is empty. If it is not empty we’ll check whether it is a valid email address, and if not we’ll set an error, otherwise we set success for the field.

if(emailValue === '') {
        setError(email, 'Email is required');
    } else if (!isValidEmail(emailValue)) {
        setError(email, 'Provide a valid email address');
    } else {
        setSuccess(email);
    }
}

Enter fullscreen mode

Exit fullscreen mode

For the password we’ll check whether it is empty or not, and if it is not empty we’ll check if it is longer than 7 characters. If not, well set an error, otherwise we’ll set it as success.

if(passwordValue === '') {
        setError(password, 'Password is required');
    } else if (passwordValue.length < 8 ) {
        setError(password, 'Password must be at least 8 character.')
    } else {
        setSuccess(password);
    }
}

Enter fullscreen mode

Exit fullscreen mode

For the password confirmation we’ll check if it is empty, and we should also check if the password confirmation’s value is equal to the password’s value.

if(password2Value === '') {
        setError(password2, 'Please confirm your password');
    } else if (password2Value !== passwordValue) {
        setError(password2, "Passwords doesn't match");
    } else {
        setSuccess(password2);
    }
}

Enter fullscreen mode

Exit fullscreen mode

Now we have every input validated, if we wanted to we could submit our form now to a specific endpoint.

Good job now you have a working form validation Javascript. Please note that you always have to validate the form inputs on the server-side as client-side validation can be easily bypassed. There are way more advanced form validation methods and libraries that we use in modern web development, but this project is a really good way to start and learn the fundamentals.

Where you can learn more from me?

I create education content covering web-development on several platforms, feel free to 👀 check them out.

I also create a newsletter where I share the week’s or 2 week’s educational content that I created. No bull💩 just educational content.

🔗 Links:

  • 🍺 Support free education and buy me a beer
  • 💬 Join our community on Discord
  • 📧 Newsletter Subscribe here
  • 🎥 YouTube Javascript Academy
  • 🐦 Twitter: @dev_adamnagy
  • 📷 Instagram @javascriptacademy

Понравилась статья? Поделить с друзьями:
  • Input output error while writing out and closing file system
  • Input output error ssd
  • Input output error ntfs linux
  • Input output error linux install
  • Input output error gparted