Recently I noticed that jQuery’s .attr() has no option to return the plain old regular text value of an attribute.  If a browser doesn’t support HTML5 input types, jQuery will return “text” for type="number".

This is actually deliberate, for the HTML5 team.  They were able to add the new input types and maintain backwards compatibility because a browser that doesn’t support HTML5 will change any unrecognized input type to text.

That’s good for those of us trying to use HTML5 right now. We can be sure the field will render just fine in IE8 or Firefox, even though neither supports type="number" right now. But it’s an awful pain when we want to provide some sort of validation fall-back or “manually” enhance a form’s UI with JavaScript in the absence of native HTML5 support.

(I got all annoyed about it because it doesn’t match the behavior of .attr() in situations where an attribute is made up [i.e. default="0"].  It also doesn’t match the way values are returned for HTML5 data- attributes [i.e. data-default="0"]. Those return the actual text, regardless of the lack or presence of any native “support” by the browser. I am hoping eventually there will be an argument to return the plain text input type.)

When it came up and I desperately needed the intended type, I remembered that had read a few things about this.  I recalled seeing example code to retrieve the text value of type rather than the DOM property of type. Of course, I couldn’t find the reference I recalled and had to spend some time with Google.

A search landed me on Brant Burnett’s site, where he had written a jQuery plugin to add an :inputtype selector. Thank you very much, Brant!  I wanted something slightly different, though, so I modified Brant’s plugin to fit my needs as follows:

/*
 * jQuery.html5type - HTML5 input type
 * Written by Brant Burnett
 * Modified by Rachael L. Moore
 * Date: 2010/12/16
 * Detects original HTML5 input types even in browsers that don't support them.
 * http://btburnett.com/2010/04/detecting-html5-input-types-on-unsupported-browsers.html
 * http://rachaelmoore.name/posts/development/javascript/jquery-plugin-original-html5-input-type/
 *
 * @author Brant Burnett
 * @author Rachael L. Moore
*/
(function($){
	// HTML5 Input Type
	$.fn.html5type = function(){
		var result = [];
		$.each(this, function(i, val){
			result[i] = m.checkType(this);
		});
		// One
		if(result.length == 1){
			return result[0];
		}
		// Many
		else if(result.length > 1){
			return result;
		}
		// None
		else{
			return false;
		}
	} // html5type
	// Methods
	$.fn.html5type.methods = {
		checkType: function(elm){
			// IE returns the original value in outerHTML
			var html = elm.outerHTML;
			if(typeof(html) !== 'undefined'){
				var found = html.match(/type=(w+)/);
				if(found){
					$(elm).data("type", found[1]);
					return found[1];
				}
			} // outerHTML
			// Other browsers can test attributes collection
			var 	attrs = elm.attributes,
				i;
			for(i = 0; i < attrs.length; i++){
				if(attrs[i].nodeName === "type"){
					$(elm).data("type", attrs[i].nodeValue);
					return attrs[i].nodeValue;
				} // type
			} // for
		} // checkType
	} // html5type.methods
	var m = $.fn.html5type.methods;
})(jQuery);

This allowed me to return the original value and use the result inside another plugin, like so:

// where I know $(this) is an individual input already
switch($(this).html5type()){
	case "number":
	 // stuff
	break;
	case "email":
	 // stuff
	break;
	case "tel":
	 // stuff
	break;
} // switch(type)