Easier autopopulating textboxes with JavaScript
Roger Johannson just posted a rather lengthy script over at 456 Berea Street that is intended to help the accessibility-conscious developer combat their designer’s label-less form design. It struck me as a little silly to repeat the label as an unnecessary title attribute, so I wondered how easy it would be to use the existing label instead of futzing with the input value. As it turns out, it’s very easy—here’s how to do it.
(Note: This technique is similar to one covered in A List Apart last year, but uses the CSS z-index instead of hiding things.)
How it works
Here’s our form markup—I am using the technique favoured by Cameron Adams, where the label does not wrap the input, but appears before it in the markup:
<form><fieldset><ol><li><label for="name">Your name</label><input type="text" name="name" id="name" class="populate" /></li><li><label for="email">Your email address</label><input type="text" name="email" id="email" class="populate" /></li></ol></fieldset></form>- Download this code: /code/visibleform.txt
Add a little CSS – the important part is the setting of position: relative on the parent LI (so the absolute positioning works):
li {position: relative;list-style: none;}label {position: absolute;top: 4px;left: 3px;color: #999;}- Download this code: /code/visiblecss.txt
As the label text is already present, we simply position it over the top of the empty form element, and then hide it underneath the input when it is focused by setting the z-index to -1. When the input loses focus, we reset the z-index unless it has some content in:
var VisibleLabel = {input_class: 'populate',inputs_to_populate: [],init: function () {if (!document.getElementById) return;var inputs = document.getElementsByTagName('input');for (var i=0,len=inputs.length; i<len; i++) {if (inputs[i].className == this.input_class) this.inputs_to_populate.push(inputs[i]);}for (var i=0,len=this.inputs_to_populate.length; i<len; i++) {this.inputs_to_populate[i].onfocus = function () {VisibleLabel.previousSibling(this).style.zIndex = '-1';}this.inputs_to_populate[i].onblur = function () {if (this.value == '') {VisibleLabel.previousSibling(this).style.zIndex = '0';}}}},previousSibling: function (el) {label = el.previousSibling;while (label.nodeName != 'LABEL') {label = label.previousSibling;}return label;}}window.onload = function () {VisibleLabel.init();}- Download this code: /code/visiblelabel.txt
Substitute your own preferred event registration technique for the clunky DOM 0 methods, and you’re good to go.
View the simple demo page—try clicking into and out of the form elements to see the label text appear and disappear.
Filed under: Javascript, Accessibility.
Technorati tags: javascript accessibility
Bookmark this article with del.icio.us
Previously: 8 Random Things
Next: Wanted: Podcast recommendations
Comments
- Nick
- 619 days ago
Here’s something very similar using jquery if anyones interested. You’ll have to view source as i can’t be arsed with creating a standalone demo.
http://homepage.mac.com/nickaliwell/etribes/- #2
- Scott Lenger
- 617 days ago
I 100% agree with using label text vs. input attribute text (per your comment on 456) but I try to avoid z-index’ing as much as possible as they lend themselves to potential issues with the IE family of browsers.
- #3
- Jack Gordon
- 610 days ago
The problem with this is what if the user has javascript turned off? I would probably set the positioning of the labels using js and leave the labels as they are for those without js.
- #4
Nice work Mr P.
The only issue I’ve found is when I scale text up in IE6, it doesn’t re-scale the input to match, leading to an ugly overflow. I’m not sure if that’s a limitation of IE, but it’s something to be aware of.