Revealing Relationships Can Be Good Form

A few days ago, a colleague of mine – someone I have known for several years, who has been doing web design for several years and harks back from the early days of ZDNet – was running through a prototype I had put together for some user testing. As with a lot of prototypes, there was an element of ‘smoke and mirrors’ to make things look like they were working.

One part of the form included a yes/no radio button, and selecting the Yes option would, in the real and final version of the form, reveal some extra content. Rather than put too much JavaScript in the prototype, I took a preverbial shortcut and created a link which I wrapped around the text next to the radio button – clicking on that link would cause the form to mimic a change event on the radio button. But it wasn’t working for him.

Why was that? Because whereas I created the form using a <label> tag for each <input> and naturally went to click on the text rather than the form control itself, he was going straight for the control (and missing the sneaky little <a href> I’d placed around the text). Bah! There goes my time-saver.

So, what did I learn? That a web professional who has used the Internet for years had neither heard of the <label> tag, nor had he ever tried clicking on the text. It just goes to show that despite its obvious uses, the label element is not as well known as it rightfully deserves to be. So, what’s a web-standards-loving guy to do? Make a bit more bleedin’ obvious, that’s what!

The Mouse Pointer Trick

OK, this is the kind of thing that causes some people outrage. A dead simple way of indicating that the label does something is to use a snippet of CSS to change the default mouse cursor to a hand. It’s derided because the hand icon is usually used for links, and some would argue that using this technique is misleading:

label {
	cursor: pointer;
}

This is not a new idea, though, and you didn’t come here for this. The point is that with something very simple, you’ve made the label element discoverable. But there are other ways that you can do this that are web standards friendly and won’t upset the purists quite so much as the hand/pointer trick. Time to wheel in the JavaScript trolley jack …

Our Old Friend AddEvent

First things, first, you’ll need to use the addEvent function (or your favourite variation thereof) that Scott Andrew devised and make that available to the document containing the form:

function addEvent(elm, evType, fn, useCapture)
{
	if(elm.addEventListener)
	{
		elm.addEventListener(evType, fn, useCapture);
		return true;
	}
	else if (elm.attachEvent)
	{
		var r = elm.attachEvent('on' + evType, fn);
		return r;
	}
	else
	{
		elm['on' + evType] = fn;
	}
}

Finding All Your Labels

Once you’ve linked to the addEvent function (or embedded it on the page), you can start to get your JavaScripting fingers a-flexing. Now, what I’m suggesting you do here is:

  • Identify all the label elements on the page by working your way through the DOM
  • Find out the value of the for attribute for each label that you uncover
  • Attach a behaviour or two to each of those label elements – and to the input that the label relates to (identified with the for attribute)

Here’s the technobabble version of the steps above:

function findLabels()
{
	var el = document.getElementsByTagName("label");
	for (i=0;i<el.length;i++)
	{
		var thisId = el[i].getAttribute("for");
		if ((thisId)==null)
		{
			thisId = el[i].htmlFor;
		}
		if(thisId!="")
		{
			//apply these behaviours to the label
			el[i].onmouseover = highlightRelationship;
			el[i].onmouseout = hideRelationship;
		}
	}
}
function highlightRelationship()
{
	var thisId = this.getAttribute("for");
	if ((thisId)==null)
	{
		thisId = this.htmlFor;
	}	
	this.className="showRel";
	document.getElementById(thisId).className="showRel";
	//if (document.getElementById(thisId).type=="text") document.getElementById(thisId).select();
}
function hideRelationship()
{
	var thisId = this.getAttribute("for");
	if ((thisId)==null)
	{
		thisId = this.htmlFor;
	}	
	this.className="";
	document.getElementById(thisId).className="";
}
addEvent(window, 'load', findLabels, false);

Using the above script, you can apply a CSS class (I’ve called it showRel) to the elements when you hover over them. How you want it to look is up to you, of course. Here are a few examples of the idea. Note: the design is not exactly what you’d call ‘fancy’, and in the examples there is one input that looks broken but it is deliberately moved away from the label it relates to, just to demonstrate that you can show the relationship even from afar.

Hopefully you’ll agree that using an unobtrusive piece of JavaScript you can make otherwise ‘shy’ elements like the label reveal their true colours. Although you might want to tone down the colours from the ones I’ve used in this demo!

About the author

Ian Lloyd founded Accessify.com, a web accessibility site, back in 2002 and has been a member of the Web Standards Project since 2003, where he is part of the Accessibility Task Force. He has written or co-authored a number of books on the topic of standards-based web design/development, most recently co-authoring on Pro CSS for Apress. He lives in Swindon, UK, a place best known for its ‘Magic Roundabout‘ and Doctor Who’s Billie Piper. (It’s not all bad, though.)

More articles by Ian

Comments