A good college buddy of mine made a comment in the last article. He asked about the default values I used in the comment form. When you click on a field, the default value goes away, allowing you to type. If the field loses focus (the “blur” event) and nothing was typed, the default value re-appears. In this article, I’m going to share this technique with you, explaining my reasoning and process.
This technique uses HTML, CSS, and jQuery. If you’ve never heard of jQuery, I recommend you checkout their site. It is one of many available JavaScript frameworks/libraries. I use jQuery almost exclusively when programming JavaScript, so expect more posts about it in the future.
The goal with this technique is to enhance the user’s experience when filling out a form. Accessibility standards require a label for every input field. This way users who cannot see the screen will understand how to fill out the form. I will begin with a basic form containing an input field, label, and submit button:
<form id="myform" action="myscript.php" method="post">
<label for="example">My Label</label>
<input id="example" name="example" type="text" />
<button>Submit</button>
</form>
At this point our form is accessible, but we want added flare. Here is the basic jQuery functionality to hide and show the label as a value in the text field.
$(document).ready(function(){
//get the text from the label and assign it as the default value for the form
defaultValue = $("#myform label[for='example']").html();
$("#example")
.data("default", defaultValue);
.val(defaultValue);
//assign a function to the focus and blur events
$("#example").bind("focus blur", function(){
value = $(this).val();
defaultValue = $(this).data("default");
//if the current and default value are the same, clear the input field
if(value==defaultValue){
$(this).val("");
}
//if the field is empty, set the value to default
if(!value){
$(this).val(defaultValue);
}
});
});
It works — Woohoo! But most of us use forms with more than one value, and I hate redundant code. Next I modify the code so that it can accept a jQuery selector and a default value to give you the functionality you need:
$(document).ready(function(){
//call the function for each field with a label
$("#myform label").each(function(){
label = $(this).html();
selector = "#"+$(this).attr("for");
createValueLabel(selector, label);
});
});
function createValueLabel (selector, defaultValue){
//assign the default value to the form selector
$(selector).data("default", defaultValue);
//if the selector is empty, initialize the default value
if(!$(selector).val()) $(selector).val(defaultValue);
//assign a function to the focus and blur events
$(selector).bind("focus blur", function(){
value = $(this).val();
//if the current and default value are the same, clear the input field
if(value==defaultValue) $(this).val("");
//if the field is empty, set the value to default
if(!value) $(this).val(defaultValue);
});
}
Much better, but it would be cool if the text changed visually when the default field was active. So lets create a CSS class, and then assign and remove it using some more jQuery code. First, the CSS class:
/* Lets make it lighter and italic */
.value-label {
color: #999;
font-style: italic;
}
Then insert the addClass() and removeClass() functions into our code and the default values will look different than if the user were to type something in the text field. This makes it easier to see what has and has not been filled out yet.
$(document).ready(function(){
//call the function for each field with a label
$("#myform label").each(function(){
label = $(this).html();
selector = "#"+$(this).attr("for");
createValueLabel(selector, label);
});
});
function createValueLabel (selector, defaultValue){
//assign the default value to the form selector
$(selector).data("default", defaultValue);
//assign a function to the focus and blur events
$(selector).bind("focus blur", function(){
value = $(this).val();
//if the current and default value are the same, clear the input field
if(value==defaultValue){ $(this)
.val("")
.removeClass("value-label");
}
//if the field is empty, set the value to default
if(!value){ $(this)
.addClass("value-label")
.val(defaultValue);
}
});
//invoke the events to initialize the default value
$(selector).trigger("focus").trigger("blur");
}
Users with a JavaScript enabled browser get added functionality, but they also get redundant labeling. That’s no good. We could remove the labels from view using the CSS rule “display: none”, but then we lose our accessibility standard. We only need to hide the labels when using the JavaScript replacement, so it makes sense to also use jQuery to add a CSS class to the labels that will hide them from the view of typical users, while still leaving them accessible for screen readers. First the CSS:
label.hide-me {
position: absolute;
top: 0;
margin-top: -500px;
}
And then add 1 more line to our jQuery function:
$("#myform label").each(function(){
label = $(this).html();
selector = "#"+$(this).attr("for");
createValueLabel(selector, label);
//use a CSS class to hide the labels from view
$(this).addClass("hide-me");
});
Put it all together, and you have a simple label replacement script that remains accessible and user friendly.
This code has been tested in FireFox, Safari and IE on Windows Vista. If you see any errors or aspects that could use improvement, please leave me a comment below. This code is free to share and change as you need it.
UPDATE for the Wordpress version of jQuery
Today I received an email from a developer who wanted to use this script, but was having trouble with the version of jQuery that is included with Wordpress. The version that Wordpress uses does not use the $ variable to call jQuery. Instead you actually need to use ‘jQuery’. So in effect, $(#id).show(‘fast’); would then become jQuery(“#id”).show(‘fast’);.
But, an easier fix is to call jQuery like this: jQuery(document).ready(function($){}. Here we call the ready function and send $ as a parameter. Then, put all of your functions inside so that they remain in scope of $. Read more about making jQuery place nice with Wordpress.
And now the updated code:
jQuery(document).ready(function($){
//call the function for each field with a label
$("#myform label").each(function(){
label = $(this).html();
selector = "#"+$(this).attr("for");
createValueLabel(selector, label);
});
function createValueLabel (selector, defaultValue){
//assign the default value to the form selector
$(selector).data("default", defaultValue);
//assign a function to the focus and blur events
$(selector).bind("focus blur", function(){
value = $(this).val();
//if the current and default value are the same, clear the input field
if(value==defaultValue){ $(this)
.val("")
.removeClass("value-label");
}
//if the field is empty, set the value to default
if(!value){ $(this)
.addClass("value-label")
.val(defaultValue);
}
});
//invoke the events to initialize the default value
$(selector).trigger("focus").trigger("blur");
}
});