Hello, please sign in or register
You are here: Home

Making HTML5 Form backwards compatible

Some of the trĂ©s chic features of the the HTML5 spec was to address some of the more common problems developers faced in building websites i.e.  form validation, video and audio embedding and make them native to the HTML syntax without requiring javascript and or plugins etc. 

At the time of writing Webkit (Safari,Chrome) and Opera have all added support in various degress. Opera (OMG!) has even provided a drop down calendar!. Which is sweet for those who hate the JQuery UI tools as much as i do. 

But to use all these cool features whilst still providing support for older browsers still requires a bit of work.

Try this demo


Code

The crux of this code provides...
  1. Does this browser have any form validation  -> No: add our own checkValidity function to the form elements
  2. Does the browser display error messages? -> No: create messages after checkValidity fails.
$(document).ready(function(){
  // Add form submit
  $('form').submit(function(){
    // AN HTML FORM WOULDN'T POST IF THERE ARE ERRORS. HOWEVER
    var b=true;
    // Loop through all the form elements and validate
    $('input', this).each(function(){
      // FOR EACH FORM ELEMENT VALIDATE
      if(!this.checkValidity()) b = false;
    });
    return b;
  });

  // Add the oninput check
  $('form input').each(function(e){

    var that = this, 
      interval;
    
    // IF checkValidity does not exist, this is not an HTML5 browser
    // Lets update it.
    if(!('checkValidity' in this)){
      this.checkValidity = function(){
        var m = {
          url : /^https?\:\/\/[a-z0-9]+/i,
          date : /^[0-9]{4}\-[0-9]{2}\-[0-9]{2}$/,
          email : /^[a-z0-9\.\'\-]+@[a-z0-9\.\-]+$/i,
          number : /^[0-9]+(\.[0-9]+)?$/i
        }
        // REQUIRED ATTRIBUTES
        var type  = that.getAttribute('type'),
          required= (that.getAttribute('required') !== null),
          pattern = that.getAttribute('pattern');            

        that.validity = {
          valueMissing  : required&&that.value.length===0,
          tooLong      : false,
          typeMismatch   : (that.value.length>0)&&(type in m)&&!that.value.match( m[type] ),
          patternMismatch  : pattern&&(that.value.length>0)&&!that.value.match( new RegExp('^'+pattern+'$') )
        };

        for(var x in that.validity){
          if(that.validity[x]){
            that.validity.valid = false;
            $(that).trigger('invalid');
            return false;
          }
        }

        return that.validity.valid = true;
      };
    }

    // ADD LISTENER TO EACH FORM ELEMENT
    $(this).bind('invalid', function(e){          
      var a = {
        valueMissing  : "Value missing",
        tooLong      : "Too Long",
        typeMismatch  : "Not a valid " + that.getAttribute('type'),
        patternMismatch  : "Invalid pattern"
      };

      $(that)
        .removeClass('error')
        .next('div.error')
        .remove();
    
      for( var x in a )
        if( that.validity[x] && (x!=='valueMissing'||that.value.length==0)){
          $(that).addClass('error') // ADD CLASS
            .after('<div class="error">'+a[x]+'</div>'); // ADD DIV
          return;
        }
    },false);

    $(this).bind('input blur', function(e){
      $(this).removeClass('error').next('div.error').remove(); // clear away error markup because `it ugly`!
      if(interval) clearTimeout(interval);
      if(e.type==='blur'){
        that.checkValidity();
      }else{
        interval = setTimeout(that.checkValidity,3000);
      }
    });
  });
  
});

Comments

Title*
Comment

Prove you are not a robot

To prove you are not a robot, please type in the six character code you see in the picture below
Security confirmation codeI can't see this!
Contact
Name*
Email never shown*
Home Page

Author

Andrew Dodson
Since:Feb 2007

Comment | flag

Categories

Bookmark and Share