Highlighting form labels

11 November 2005

Here's a nice little UI enhancement for forms that I knocked up today. I don't know if you have seen anything like it before? If so, let me know where, and I can see about improving my scripts. Talking of improving the script, I've realised there is a far better way of achieving this than how I have done it, which I will explain in a minute. First of all, go down to the comment form at the end of this post and fill in a few fields. Notice the labels become highlighted as each form field gets focus. Here's how it's done. First of all, get every input element in the page with a type attribute of text. Loop through these and add the onsubmit and onblur event handlers required to trigger the functions which do the real business. This is done with the prepareLabels function shown below, although now I think about it, prepareInputs might have been more appropriate. function prepareLabels () { if (!document.getElementsByTagName('input')) exit; input = document.getElementsByTagName('input'); for (i = 0 ; i < input.length ; i++) { if (input[i].type == 'text') { input[i].setAttribute("onfocus","on(this)"); input[i].setAttribute("onblur","off(this)"); } } } Next up I have two functions. One that changes the style.color property to the highlight color onfocus, and the other that reverts the property onblur. I realise that I could combine these into one function with a simple if statement, and I will do in the next version of this. The two functions are shown below. function on(field) { temp = field.parentNode; dl = temp.previousSibling; label = dl.firstChild; label.style.color = '#a00'; } function off(field) { temp = field.parentNode; dl = temp.previousSibling; label = dl.firstChild; label.style.color = ''; } In a nutshell, these navigate their way throught the DOM tree of dd and dl, finish up on the label element and apply the new color through the style.color property. And that's pretty much it. Simon Willison's addLoadEventfinishes the job by attaching the prepareLabels function to the onload event. But what about the textarea your thinking, right? Well, at the moment I actually have a third function which duplicate's the prepareLabels function but gets the textareas instead. function prepareText () { if (!document.getElementsByTagName('textarea')) exit; input = document.getElementsByTagName('textarea'); for (j = 0 ; j < input.length ; j++) { input[j].setAttribute("onfocus","on(this)"); input[j].setAttribute("onblur","off(this)"); } } I know this is not a nice way of doing things, and it will be improved. The next stage I want to think about now is making this much more generic. A better solution would be to use the for attribute of the label and match it with the id value of the input that is currently in focus. That way, we are not relying on our form being layed out with definition lists as I currently am. Anyway, that's something to think about while I'm on my way down to d.constructbright and early tomorrow morning.