Friday, December 17, 2010

Provide custom validation messages using setCustomValidity in HTML 5 pages

If you have come through my other note on "Form validations on HTML 5", you already know that HTML 5 is promising enough to make validations better and native. Just set the right properties for the INPUT elements and HTML 5 gives you on-the-fly validations with less code. But, in some scenarios, we might have to include additional logical validations, in which case, setCustomValidity() function can be used to logically decide and set your own validation messages.

Below is a simple sample code that will demonstrate the usage of setCustomValidity() functionality.
<!DOCTYPE html>
<html>
<head><meta charset="utf-8">
<title>HTML5 Sample Validation Page</title>
<style type="text/css">
body
{
    font-family:Arial;
    font-size:12px;
}
.valid
{
    color:#000000;
}
.invalid
{
    color:#FF0000;
}
</style>
</head>
<body>
<form id="form1" method="post">
<label>Age: <input type="number" required="true" value="50" min="18" max="60" step="1" oninput="validate(this)"> (between 18 and 60)</label><br /><br />
<div id="validateMsg"></div><br />
<div id="validity"></div>
<script>
function validate(input) {
    //logically decide and set custom validation message
    if (input.value == "20" || input.value == "30") {
        // set custom validation message
        input.setCustomValidity('Your Age (' + input.value + ') is in a transition phase.');
    } else {
        // reset the validation message - makes it valid for checkValidity function
        input.setCustomValidity('');
    }
    document.getElementById('validateMsg').innerHTML = 'Validation Message: "' + input.validationMessage + '"';
    document.getElementById('validity').innerHTML = 'checkValidity function output: "' + input.checkValidity() + '"';
}
</script>
</form>
</body>
</html>
Concept:
In this example, Age input is expected to accept only values between 18 and 60. Additionally, 20 and 30 ages are also treated as Invalid (of course, unusual scenario). This is done by using setCustomValidity() function which will internally set the validationMessage property of the input control. The HTML 5 form validation function checkValidity() takes the validationMessage in to account and provides output as shown below, in Google Chrome.

Valid Input:

Invalid Input:

Custom In-valid Input: (20 and 30 are not accepted):

In valid scenarios, validationMessage is an empty string and checkValidity function returns true. In In-valid scenarios, including our custom invalid scenarios, checkValidity function returns false and validationMessage is returned based on the custom message set.

Form Validation using checkValidity and Validity in HTML 5 using JavaScript- Sample Code

The next major version of the HTML standards (HTML 5) seem to have numerous improvements over the current standards. Most of the functionalities, for which the developers has to write extensive custom code, will get reduced to a certain extend by the launch of new standards.

The below sample shows how to perform a FORM validation for an HTML 5 input element using the newly introduced "Validity" property associated to an input element. This will also demonstrate the usage of checkValidity() function which can be used to identify whether the the form elements are all validated to proceed with the server communication.

Skill level: For Beginners

Sample Code:
<!DOCTYPE html>
<html>
<head><meta charset="utf-8">
<title>HTML5 Sample Validation Page</title>
<style type="text/css">
body
{
    font-family:Arial;
    font-size:12px;
}
.valid
{
    color:#000000;
}
.invalid
{
    color:#FF0000;
}
</style>
</head>
<body>
<form id="form1" method="post">

<label>Age: <input type="number" required="true" value="50" min="18" max="60" step="1" oninput="validate(this)"> (between 18 and 60)</label><br /><br />
<div id="validateMsg"></div><br />
<div id="validity"></div>
<script>
    function validate(input) {
        var out = document.getElementById('validateMsg');
        if (input.validity) {
            if (input.validity.valid === true) {
                out.innerHTML = "<span class='valid'>" + input.value +
                            " is a valid age.</span>";
            } else {
                out.innerHTML = "<span class='invalid'>" + input.value +
                            " is not valid age.</span>";
            }
        }
        document.getElementById('validity').innerHTML = "checkValidity() output: <span class='invalid'>" + input.checkValidity() + "</span>";
    }
</script> 
</form>
</body>
</html>

Concept:
The input element is a number element (that accepts "Age") in this example, with maximum and minimum values set in the design mode. [If more information is needed on the Input elements, refer here.] During the user input event, a JavaScript function validate() is called. This function validates the input value using the input.validity.valid property and provides appropriate message, after checking for the support of this functionality.

checkValidity() function is called to check and understand the value that it returns for the successful and unsuccessful validation scenarios.

Here are the output screens:

Valid Input:

Invalid Input:

As you can see, the checkValidity() always seems to return false. It returns true for values less than 10. It is being suspected that the inadequate browser support is one reason behind this weird behavior OR i'm missing something. However, as per the documentation here, this function will help us to check and trigger functions based on the invalid/valid state of one/multiple elements, thereby assisting us in form validations.

In the above code, the script tag is provided inside the body tag, for the sake of easy understanding. Keep it inside the HEAD tag, as it is usually done.

Sunday, December 12, 2010

HTML 5 Sample page with sample code for newly introduced INPUT elements

Here is a sample code for an HTML 5 page with the new input elements, which has the minimum set of properties defined so as to get a feel of how the new HTML standards are coming up. This will also give us an idea on how these changes are going to affect the user experience once they gets implemented in web pages.

Let us start by specifying the HTML 5 doc-type as shown below.
<!DOCTYPE html>
At the time of this writing, below are the type of input elements that are available. Most of these new element types are being supported in Google Chrome.

Keyword State Usage
search Search <input type="search">
number Number <input type="number">
range Range <input type="range">
color Color <input type="color">
tel Telephone <input type="tel">
url URL <input type="url">
email E-mail <input type="email">
date Date <input type="date">
month Month <input type="month">
week Week <input type="week">
time Time <input type="time">
datetime Date and Time <input type="datetime">
datetime-local Local Date and Time <input type="datetime-local">

Here is the sample HTML code showing the basic features of the newly introduced input controls. For sake of simplicity, the properties are kept to a minimum. Even the layout beautification is ignored.

Simple Sample Code:
<!DOCTYPE html>
<html>
<head><meta charset="utf-8">
<title>HTML5 Sample Page</title>
<style type="text/css">
body
{
    font-family:Arial;
    font-size:12px;
}
</style>
</head>
<body>
<form id="form1" method="post">
Search:
<input type="search" placeholder="Search text here"><br />
Number:
<input type="number" value="50" min="40" max="60" step="5" autofocus="true"><br />
Range:
<input type="range" value="50" min="40" max="60" step="5"><br />
Color:
<input type="color" value="#000000"><br />
Telephone:
<input type="tel" placeholder="999" pattern="[0-9][A-Z]{3}" title="A part number is a digit followed by three uppercase letters."><br />
URL:
<input type="url" value="http://www.google.com"><br />
Email:
<input type="email" multiple value="me@somewhere.com"><br />
Date:
<input type="date" max="2050-12-31" min="2000-01-01" value="2010-01-01"><br />
Date Time (Time zone information included):
<input type="datetime" value="2000-12-31T00:00+05:30"><br />
Local Date Time (No Time Zone information):
<input type="datetime-local" value="2000-12-1T00:00"><br />
Month:
<input type="month" max="2000-10" min="2000-02" value="2000-04" step="2"><br />
Week:
<input type="week" max="2000-W50" min="2000-W05" value="2000-W06" step="2"><br />
Time:
<input type="time" max="23:00:00" min="01:00:00" value="04:30:00" step="5"><br />
File Upload:
<input type="file" accept="image/*" name="image" multiple onchange="updateFilename(this.value)"><br />
<input type="submit" value="Submit"/>
</form>
</body>
</html>

The above sample code also includes the usage of new properties like multiple, pattern, placeholder, autofocus, min, max, step etc.

Here is how it looks in Google Chrome.

Yes, it looks ugly (though it serves the purpose)! Feel free to copy the code and beautify/change it as needed. Let me know whether there is any changes, since the specification is fairly new.

References:
http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary
http://www.whatwg.org/specs/web-apps/current-work/multipage/common-input-element-attributes.html#the-multiple-attribute