Friday, June 17, 2022

Hack 5. Easily Implement Form Validation Without JavaScript


HTML5 includes powerful form validation that works seamlessly with the slew of new input types.

Form validation is fun again. Well, maybe not fun, but more fun than it ever was before. OK, let’s just admit it, form validation sucks. It’s not fun, but it is necessary. In the past you would write a form and then run some very custom code to make sure all your inputs contained what they were supposed to contain. This was done in one of two ways: on the server or on the client. For server-side validation you would submit your form and run server-side code to make sure all your requirements were met, and if they weren’t you would reload the page with an error or two on it telling the user where the problem was. Client-side validation worked in pretty much the same way, except you would run some JavaScript before the form was submitted to make sure all your conditions were met. For the record, the best kind of validation is when you do both. You should start with validation on the client to give the user an immediate response, and then revalidate on the server to make sure your response wasn’t being hacked.

HTML5 isn’t going to help you with server-side validation, but it sure will make it easier on the client. HTML5 once again takes a tried-and-true web standard and reinvents it as native browser functionality. Let’s dive in!

What Does It Mean to Validate?

In HTML5 every input has the ability to have validation engaged, and a form cannot be submitted if it doesn’t validate. In order for the form to validate, every input needs to have its validation criteria met. It’s pretty simple: every input has a method you can call to see if it will meet a validation test. Let’s look at a form containing an input of type number:

<!DOCTYPE html>
<html>
<body>

<form name="myForm">
  Quantity (between 1 and 5):
  <input type="number" name="quantity" min="1" max="5" value="11" />
  <input type="submit" />
</form>

</body>
</html>

Now let’s check it with JavaScript:

<script>
if(document.myForm.quantity.checkValidity() === false){

alert('fail');
}

</script>

When the value of quantity is greater than 5 the alert will be fired. Now let’s try something a little different. Instead of checking the input itself, let’s just check the form. Here is the new JavaScript:

<script>
//myForm is the name of the form element
if(document.myForm.checkValidity() === false){

alert('fail');
}

</script>

Notice that the validity state rolled up to the form. If any one of the inputs within the form doesn’t meet the criteria for validation, the form rule will return false as well. This is a key feature when you have long forms. For instance, if I have a form with 25 input fields that need to be validated, I don’t want to have to go through the form with JavaScript and check each input field—this would require 25 different DOM hits. Instead, I’d rather check the form and have it determine whether all the necessary input criteria are met on each of the 25 inputs.

Validation Criteria

So, we know how we can check to see if a form is valid or not, but how do we set the criteria we want to validate against? Well, there are really three ways to do this in HTML5.

The required attribute

First, we can simply add the required attribute to an input, and the input will return a true state for its validity value only if the element has a value and the value matches the required input criteria. In the following example, the input has to be a number between one and five:

<input type="number" name="quantity" min="1" max="5" />

The pattern attribute

The new pattern attribute is pretty slick, especially for people who like to write regular expressions. In this case you set a regular expression to the pattern attribute, and your input will validate against that pattern in order to have the validity value return true:

<input type="text" name="quantity" pattern="[0-5]{1}" />

Notice that the type was changed to text in order for the pattern to make the input invalid; we need to remove the number type, as that will supersede the validation criteria. If the type and pattern conflict (by requiring results that exclude each other), the validation criteria will never be met, and the form will never validate.

Measurable attributes

Some input types have comparative criteria such as email, which require a strict input pattern. Other input types have attributes such as min and max that must be satisfied before the input can be considered valid. Let’s look at our first input example again:

<form name="myForm">
  Quantity (between 1 and 5): <input type="number" name="quantity" min="1" 
max="5" />
  <input type="submit" />
</form>

In this case the number that is input must meet the min and max criteria in order to be considered valid. For example, the number 11 would not validate but the number 4 would validate. In a similar manner we have the email type:

<form name="myForm">
  Enter Your Email: <input type="email" name="myEmail" />
  <input type="submit" />
</form>

The email type looks for a value that meets traditional email criteria that would match a regular expression such as this:

var emailTest = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/;

If the value of the input doesn’t have a username, an at sign (@), and a domain, it’s considered invalid.

Let’s Call This Validation Thing Off

Sometimes you may want to skip validation. A few HTML5 validations allow you to do this. The first is the formnovalidate attribute. As you can guess, if you apply this attribute to a button or an input whose type is submit, the validation does not stop the form from submitting. This attribute can be placed as follows:

<form name="myForm">
  Quantity (between 1 and 5): <input type="number" name="quantity" min="1" 
max="5" />
  Enter Your Email: <input type="email" name="myEmail" />
  <input type="submit" />
<button type="submit" formnovalidate>save</button
</form>

Note that the form is still invalid. If you call the checkValidity() method on this form, it will still return false. In the case of the formnovalidate attribute, you simply ignore whether the form is valid or not when you submit.

The second way to escape validation is with the novalidate attribute. In a similar manner, the novalidate attribute is added to the form element itself, and every button and input whose type is submit will skip the validation stem and submit the form directly:

<form name="myForm" novalidate>
  Quantity (between 1 and 5): <input type="number" name="quantity" min="1" 
max="5" />
  Enter Your Email: <input type="email" name="myEmail" />
  <input type="submit" />
<button type="submit" >save</button>
</form>

The Constraint Validation API

The HTML5 spec makes allowances for us to be more specific with our validation errors. In the previous example form, the user must enter a number between one and five to not receive an error. If we wanted to update the error message to be a little more suitable, we would add a custom message with the setCustomValidity() method:

<form name="myForm">
  Quantity (between 1 and 5):
  <input type="number" name="quantity" min="1"
   max="5" oninput=  "updateMessage(this)"/>

  Enter Your Email: <input type="email" name="myEmail" formnovalidate />
  <input type="submit" />
</form>

<script>

myForm.quantity. setCustomValidity('looks like your numbers ... between one 
and five')

function updateMessage(input){

if(input.value ==""){}
input.setCustomValidity('');

}


</script>

Our form will now give us an option for a friendlier, more helpful user error. Notice that we had another method in the <script> tag and set it to the oninput of the input. When you use setCustomValidity() you automatically trigger the other portion of your Constraint Validation API to return false when you call the checkValidity() method. In order to use a custom method and still have the form be considered valid when the criteria are met, you need to throw in some JavaScript to clear out the setCustomValidity() method once the validation criteria are met (in this case, once the form is not blank). I still think the W3C has some room to make this even easier for web developers in upcoming versions of the spec. This is functionality you should be able to access without JavaScript.

Developers aren’t the only ones using the Constraint Validation API. The user agent uses the same API when it sets up the pseudoclasses for its CSS. With CSS3 we can change visual cues based on the “state” of a validation field. We have access to two pseudoclasses (more on this later) to use for visualizing cues: :required, for elements that are marked as required; and :invalid, for elements that are marked as invalid. Unlike the form-level validation that occurs when the page submits, the pseudoclasses are based on the current state. This will give users strong visual cues. Let’s look at an example with a contact form where the name is required, and the phone number and email address are not required:

//our css
<!DOCTYPE html>
<html>
<body>

<style>
input {display: block;
border: 1px solid #ccc;
}


:invalid{
border-color: #DB729C;
  -webkit-box-shadow: 0 0 5px rgba(27, 0, 97, .5);
}

:required{
border-color: #1BE032;
  -webkit-box-shadow: 0 0 5px rgba(57, 237, 78, .5);
}

</style>

//our form
<form name="myForm" >
 Enter Your Name: <input type="text" name="myName" required >
 Enter Your Phone Number:
 <input type="tel" name="myPhone" pattern="\d\d\d-\d\d\d-\d\d\d\d" />
 Enter Your Email: <input type="email" name="myEmail" />
 <input type="submit" />

</form>

Figure 1-4 shows our rendered view.


Figure 1-4. Form with validation for required field

The CSS in the preceding code snippet adds a red border around the invalid field. The red border will remain until the proper content is entered.

We had to do this in two different ways due to browser support. The easy way was the method we used for the email address. The input knows what a valid input address looks like (i.e., the pattern of the address, not whether it works). So once a valid string is set to the proper value, the field will no longer appear with a red border.

The method we used for the telephone number was a little more difficult. Most modern browsers “partially” support the tel input type for HTML5. One thing that isn’t supported is whether what is entered is indeed a valid telephone number. I could easily type my name into that field and it would validate. Here, we needed to go back to the pattern attribute and use a regex to determine whether it was a phone number. This particular regex isn’t very useful, as it only checks to see if there is a digit string that matches this pattern: xxx-xxx-xxxx. It doesn’t satisfy the use of brackets around an area code, nor does it support any numbers in a format other than that used in the United States. We’d need a more robust regular expression for that.

It would appear that our form is complete and ready to throw onto our website, but there are a few final details to point out. We assigned a required state to the name, as we desired, but note that a partially filled input will stop the form from submitting as well (the form field is invalid but not required, but this form must validate before it can be submitted). Adding novalidate to the form allows not only the invalid inputs to submit, but also the required ones as well. There is no clear solution for avoiding this, so let’s move forward and address the issue with the user if it becomes a problem.

Before we try this form again, let’s go back and update the Enter Your Name field to display a more user-friendly error message:

<style>
input {display: block;
border: 1px solid #ccc;
}

:invalid{
border-color: #DB729C;
  -webkit-box-shadow: 0 0 5px rgba(27, 0, 97, .5);
}

:required{
border-color: #1BE032;
  -webkit-box-shadow: 0 0 5px rgba(57, 237, 78, .5);
}

</style>

//our form
<form name="myForm" >
 Enter Your Name:
 <input type="text" name="myName" placeholder="Enter Your Name"
  oninput="updateMessage(this)" required>
 Enter Your Phone Number:
 <input type="tel" name="myPhone" pattern="\d\d\d-\d\d\d-\d\d\d\d" />
 Enter Your Email: <input type="email" name="myEmail" />
 <input type="submit" />

</form>

<script>
document.myForm.myName.setCustomValidity("To join our list..., please enter 
it here")

function updateMessage(input){

if(input.value ==""){}
input.setCustomValidity('');

}

</script>

There we have it. In the past, such validation would have required a good amount of custom JavaScript. Now it can be done with the simplicity of HTML5!




 


SHARE THIS

Author:

urdufundastory.blogspot.com is the first of its kind of trendsetting venture existent in Pakistan. It is for the first time in the history of this nation that a large scale project of such nature, evolved from an extraordinarily revolutionizing concept to a practical fulfillment.

0 Comments: