Click here to Skip to main content
Click here to Skip to main content

Simple to use Cross-browser Smart Masks and Form Validation

, 14 Nov 2006
Rate this:
Please Sign up or sign in to vote.
This article proposes a path for simple-to-use but effective cross-browser smart masks and data validation, which involves browser capabilities identification, cross-browser key capturing and other features, based on W3C standards, Microsoft standards, and my own experience

Disclaimer

The author does not accept responsibility for any effects, adverse or otherwise, that this code may have on you, your computer, your sanity, your dog, and anything else that you can think of. Use it at your own risk. (Deja Vu? I also love the Allegro disclaimer).

Quick and Dirty Tour

So you don't like to read long articles or you don't have time for it, then just download the source files, run the demo HTML files on your preferred browser.

Background

Although the inner works require you to be an advanced Web developer to understand and improve it, you need only to have basic knowledge of HTML and JavaScript to use the Framework.

Introduction

Building cross-browser masks and validating data aren't simple tasks. And there isn't a definitive solution for this topic, but we can, with some assumptions, come up with a feasible solution. Before getting into the code, let's revisit some keywords:

  • Max Size: Do not allow infinite data entry on the UI fields.
  • Events: The most difficult cross-browser topic. We'll discuss the differences of keyPress x keyDown events on major browsers for masks purposes.
  • Masks: Do not allow the user to enter incompatible data into textboxes, like “ABC” in number-only fields.
  • Smart Masks: Do not allow the user to enter invalid data into textboxes, like “99:99” in a time field.
  • Validation: There are some data types that would be impractical to check as the user types, so the system checks the entire input set for inconsistencies on the forms submit event.
  • Cross-Browsing (not breaking on other browsers): The system should run on any major browser seamlessly.

Basics (or Talking is Cheap...)

Let's start with the page that will have some data entry fields ready to be filled. The validationDemo.htm page will look like the image below:


Not much of a beautiful page, but it will help us to test our strategy. Let’s take a look at its HTML code:

...
    <fieldset>
        <legend>Search block</legend>
        F1 number(3)<input ai_name="myNumber" type="text" ai_block="search">
        <br />
        F2 number(3,2) <input id="number3point2" type="text" ai_block="search" />
...

As you can see, no JavaScript is present on the page (except for the configuration call at the bottom of the page), and no information about how the fields should behave either.

In the demo, we have two distinct blocks that should be validated separately. The next thing to do is to create an uncoupled way of configuring our pages. For complex systems, we could build an XML file for every page that needs validation, but for our small demo, let's build a single XML file (validationDemo.xml).

...
<validation>
    <field name="myNumber" block="search|insert" personality="number"
        precision="3,0" required="true" />
    <field id="number3point2" block="search" personality="number" precision="3,2" />
    <field id="date" block="search" personality="date" />
...

The XML is almost self-explanatory, as it only specifies each field behavior. For instance, the number3point2 text field should allow 3 digits before the decimal point; and 2 after and the date field should allow (guess what) only dates. We have two distinct ways of finding elements on pages: by ID and by NAME. If you have a single element that does not repeat its behavior through different blocks of the UI, the ID is your choice. Now take a look at the F1 and F7 fields of our page. They behave the same way and are present in different blocks of the page. In this case, we set its configuration by NAME, so we do not duplicate the XML tags, we just inform that the element is present on “search” and “insert” blocks. The NAME attribute does NOT map to the HTML NAME attribute, for reasons far beyond the scope of this article.

Smart Masks

Smart masks, as I conceive, should come in pairs: one real-time filter mask and a post-validation companion function. Our little Framework has some mask ready to use and to serve as an example.

All mask functions can be attached to the pageValidator dynamically during the setup, without generating errors, even if you need it. We accomplish that by having an array of masks inside the pageValidator and testing for the existence of a particular mask before using it.

...
        case 'time' : //15:00
        mask = "TimeMask";
...
        if( mask != null )
            if( pageValidator.Masks[mask] != null )
                oSrcElement.onkeypress = pageValidator.Masks[mask];
...

Since it is an advanced feature, let’s keep walking for the last act of our show, the validation of the input.

Validation (or Trust, but Check)

By now, we have only one more step to go: validation of the inputs. This step is performed when the user clicks on the Validate button and it triggers the validation of the block specified as a parameter, as in your test page:

<input type="submit" value="Validate Search" id="Submit2"
    onclick="return pageValidator.IsValidForm('frmPage', 'search');" />

You must pass the form to be validated. The section if omitted will be all by default, where the entire form would be validated. Since each page object has its intelligence within, the IsValidForm function will only check the integrity of those rules, applying an "exception" CSS class to the element with problems.

The "]>" Characters vs. XHTML Validation

A few comments about the ]> characters follows: 'till the present time, no browser is compliant with the custom DTD used in the demo page, despite the fact it is complete valid XHTML page (using the W3C validation). This means that your page will show the ]> characters if you use this approach. Another way to get a valid XHTML page is by creating a custom DTD, by downloading the W3C DTD file and adding your rules. It seems that it should be avoided at all costs, but we have few options these days.

If page validation is no concern for you yet, you may safely remove the custom block from the HTML DOCTYPE TAG and be happy!

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

Conclusion

And that’s it for the simple-but-effective abstraction layer! As you could see, it’s very simple to use, so it can be applied easily on small or mid sized Web systems. Its inner works may not be simple or easy to understand at first because of the complex divergences of major browsers. All the code presented is free of copyrights and may be used freely as long as you maintain the references to its authors.

References

The best resources you could find:

History

  • 07-27-2006: Original article
  • 08-02-2006: Changed function _GetElementsByAttribute(aName, aValue, tName) in events.js (lines 117-118) file to accommodate some Opera issues related to null objects. Thanks to cowdart who brought my attention to this issue.
  • 11-14-2006: Simplified the article, focused on the use rather than inner works
  • 11-16-2006: Added a UML model (jude community software) to help localize methods and classes

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Roberto Colnaghi
Software Developer
United States United States
I'm a passionate developer and videogame player.
Been in touch with Objective-C, Javascript, C#, C, Guild Wars 2, Tera and many more.
 
Javascript is one of my favorite languages.
Follow on   Twitter   Google+

Comments and Discussions

 
GeneralVery good PinmemberLeandro Souza24-Nov-06 5:42 
GeneralRe: Very good PinmemberRoberto 'Obi-Wan' Colnaghi Junior24-Nov-06 6:06 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140721.1 | Last Updated 14 Nov 2006
Article Copyright 2006 by Roberto Colnaghi
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid