Placeholder Attribute Support in ALL browsers

Included along with jQuery, the following code allows you to include the HTML5 placeholder attribute work in older browsers. The idea is to find all the input elements that have a placeholder attribute that the browser is ignoring since it doesn’t understand. Check to see if the input value is empty. If it is empty, include the placeholder value temporarily as the value (preferably making it look like a placeholder). If the user focuses on the input, clear the placeholder value, which is the default behavior in browsers that support the placeholder value. When the user exits the input box, the script checks to see if there is a value. If not, reinstate the value of the placeholder.

The second script is for when the user submits the form: we want to make sure that the form is not alwasy submitting the placeholder value. The main issue with this function is that the user cannot actually enter data that matches the placeholder, so, if you’re going to use this function, make sure that the placeholder value is not one that a user would intentionally submit. For example, use ‘first name’ and ‘last name’ for names, rather than ‘john’ and ‘doe’. Use ‘phone number’ or ‘415.555.1212’ for phone numbers, and other implausible values, etc.

  //make HTML5 placeholders work in non supportive browsers
  $("input[placeholder]").each(function(){
    if($(this).val()==""){
     // $(this).addClass('hasplaceholder');
      $(this).val($(this).attr("placeholder"));
      $(this).focus(function(){
        if($(this).val()==$(this).attr("placeholder")) $(this).val("");
       // $(this).removeClass('hasplaceholder');
      });
      $(this).blur(function(){
        if($(this).val()==""){
	  // $(this).addClass('hasplaceholder');
           $(this).val($(this).attr("placeholder"));
        }
       });
    }
  });

$('form').submit(function(evt){
	$('input[placeholder]').each(function(){
		if($(this).attr("placeholder") == $(this).val()) {$(this).val('');}
	});
});

Here are the lines explained:

Finds and iterates thru each input with a placeholder attribute:
$("input[placeholder]").each(function(){

Checks to see if the value is empty
if($(this).val()==""){

Commented out, you can add this line to add a class to the inputs that currently don’t have a value, so you can stylize them to look like placeholders (in other words, change the color to light grey using CSS):
// $(this).addClass('hasplaceholder');

Find the value of the placeholder attribute and sets it as the value of the value attribute
$(this).val($(this).attr("placeholder"));

Create an onFocus event handler
$(this).focus(function(){

When focused, checks to see if the current value matches the value of the placeholder. If so, it clears the placholder
if($(this).val()==$(this).attr("placeholder")) $(this).val("");

If you included the class to stylize the placeholder look and feel, remove it when the user is focusing on this input
// $(this).removeClass('hasplaceholder');

Close out the onFocus event handler
});

Create an onBlur event handler for when the user exits the input box
$(this).blur(function(){

Check to see if the input box is empty (the user has NOT entered any data)
if($(this).val()==""){

If the value is empty, we’re going to not just put the placeholder in, we should also include a class to be able to stylize it as a placeholder would look:
// $(this).addClass('hasplaceholder');

Put the value of the placeholder in the value — as we did on page load above.
$(this).val($(this).attr("placeholder"));

Close out all the set up stuff
}
});
}
});

We also need to ensure that the element has a legitimate value when the form is sumbitted:

We create an onSubmit event handler:
$('form').submit(function(evt){

We go thru all the inputs that have the placeholder attribute:
$('input[placeholder]').each(function(){

If the current value matches the placeholder value, we clear it before sumbitting:
if($(this).attr("placeholder") == $(this).val()) {$(this).val('');}

We close out the function:
});
});

Note that if the element is ‘required’, the submit function would be different and we would test to see if the browser supports the placeholder attribute before doing any of this, but i am just providing a small snippet to show how easy (and possible) it is to make older browsers support HTML5 form features.

IE6 and IE7 implicit Label bug

HTML and XHTML specifications allow both implicit and explicit labels. However, IE6 and IE7 do not correctly handle implicit labels. When including implicit labels, IE6 and IE7 treat the input as one label and the text within the element as a second label. In other words, if you include padding, margin, bakcground images, or, in the case of IEs, hasLayout like “zoom”, the styles will be added to both the input part of the label and to the text part of the label.

For example,

<label>First name <input type=”text” name=”firstname”></label>

IE6 and IE7 interpret the code as if you wrote:

<label>First name</label>
<label><input type=”text” name=”firstname”></label>

This is how IE6 and IE7 render:

implicit label in IE7

This is how it should be rendered:

implicit label in IE8

Generally, this isn’t a major issue, which is probably why I couldn’t find documentation on this bug. However, if you want to put a background image between the input and the text, if you want to put a border around the label, or if the label is floated left and you need to give “hasLayout” for IE6, that’s where it gets tricky.

(note: if you use zoom: 1 on your label, the label will display on two lines: one for the input, and the other for the text)

The implicit label is valid according to the w3c. See the W3C Label Specifications. The w3c states:

“ To associate a label with another control implicitly, the control element must be within the contents of the LABEL element. In this case, the LABEL may only contain one control element. The label itself may be positioned before or after the associated control.”

Some may argue “just use explicit labels”, and there are accessibility arguments around that. However, old versions of JAWS, in forms mode, did not read the label for implicit labels on checkboxes and radio fields. I believe that has been fixed.

My fix was inane, yet valid. I assume this is such an esoteric bug that I don’t need to create recommendations on fixing it. I just wanted to document it in case someone else comes across this bug. But, if you do come across this bug, the easiest solution is to create explicit labels!

Documenting bugs

I wrote this in the summary, but let me reiterate:

Even though IE6 has been around for nearly a decade, there are still some undiscovered bugs. As we push the limits of what new browsers can do, we go beyond the limits of what old browsers are capable of. As we push the limits, new bugs may be discovered. You know you found a new bug when you can find no documentation on it. When you find a new bug, document it. You may have pulled your hair out because of this bug you’ve discovered. Save someone else from that pain!