So I was perusing my
delicious history the other day, and happened along this post:
http://woork.blogspot.com/2008/04/improve-form-usability-with-auto.html
I was bored, so I thought I'd hack together my own version, especially given that someone else has laid out the blueprints already! Wheel++
I kept in mind some of the comments from the original post, namely keeping the javascript unobtrusive.
Here's a
demo for download.
On with the details:
First we'll mark up a simple form:
<form action="" method="get" accept-charset="utf-8">
<p>
<div class='label-wrapper'><label for='email'>Email: </label></div>
<div class='element-wrapper'>
<input type='text' name='email' id='email' />
<div class='form-hint' id='email-form-hint'>
Enter your email address
</div>
</div>
</p>
<p>
<div class='label-wrapper'><label for='foo'>Foo: </label></div>
<div class='element-wrapper'>
<input type='text' name='foo' id='foo' />
<div class='form-hint' id='foo-form-hint'>
Enter something here
</div>
</div>
</p>
<p>
<div class='label-wrapper'><label for='bar'>Bar: </label></div>
<div class='element-wrapper'>
<input type='text' name='bar' id='bar' />
<div class='form-hint' id='bar-form-hint'>
Enter something here
</div>
</div>
</p>
<p><input type="submit" value="Continue →"></p>
</form>
Here we let you keep it simple, merely adding a div of class "form-hint" to add a hint to a field. Note also that the hint's ID must match the form field's ID, in the form of "[ID]-form-hint"
Next we'll add some style:
<style type="text/css" media="screen">
.form-hint-wrapper {
background:#fff;
padding:0;
position:absolute;
z-index:999;
}
.form-hint {
background:#def;
clear:both;
padding:5px 10px;
display:none;
}
/* thanks to http://www.csskarma.com/lab/css_arrows/ */
.arrow-up {
background:transparent none repeat scroll 0 0;
left:10px;
top:0;
width:20px;
}
.arrow-up-1 {
border-right:10px solid #def;
border-top:10px solid #fff;
float:left;
}
.arrow-up-2 {
border-left:10px solid #def;
border-top:10px solid #fff;
float:left;
}
.arrow-up-1, .arrow-up-2 {
height:0;
overflow:hidden;
width:0;
}
</style>
Finally finish off with the javascript guts:
<script type="text/javascript" charset="utf-8" src="http://ajax.googleapis.com/ajax/libs/prototype/1.6.0.3/prototype.js"> </script>
<script type="text/javascript" charset="utf-8" src="http://ajax.googleapis.com/ajax/libs/scriptaculous/1.8.2/scriptaculous.js?load=effects,builder"> </script>
<script type="text/javascript" charset="utf-8">
Event.observe(window, 'load', init_hints);
function init_hints() {
$$('.form-hint').each(function(hint){
var hint_parent = hint.parentNode;
hint_parent.makePositioned();
var arrow_wrapper = Builder.node('div', {'class': 'arrow-up'},
[
Builder.node('div', {'class': 'arrow-up-1'}),
Builder.node('div', {'class': 'arrow-up-2'})
]
);
hint_clone = hint.cloneNode(true);
Element.setStyle(hint_clone, {'display': 'block'})
var hint_wrapper = Builder.node('div', {'class': 'form-hint-wrapper', 'style': 'display:none'},
[arrow_wrapper, hint_clone]
);
var el = $(hint.id.replace('-form-hint', ''));
Event.observe(el, 'focus', element_focused);
Event.observe(el, 'blur', element_blurred);
hint.replace(hint_wrapper);
});
}
function element_focused(el) {
var wrapper = $(el.target.id + '-form-hint').parentNode;
new Effect.Appear(wrapper, {'duration': 0.25})
}
function element_blurred(el) {
var wrapper = $(el.target.id + '-form-hint').parentNode;
new Effect.Fade(wrapper, {'duration': 0.25})
}
</script>
The script will find all elements on the page of class "form-hint", then wrap them in another div that contains an arrow pointing to the form element, using only CSS.
That's about it - feel free to hack the CSS to change the hint colors, etc...
Download the demo.