When you have limited space on your home page or any other page for that matter, it is nice to provide a little more helpful information for the use where form space is limited. Now, by just adding a single attribute to your input text, your will get the gray help text in your input box.
<input class="standout" type="text" />hintvalue="Search ..." class="smallbox" name="s" type="text" autocomplete="off" />
Just add the javascript from this article and any styles that you want and you are done. Here is a working example. Click in the boxes and watch it work.
How it works
The guts of the work is done in javascript in two objects. The first is a simple object called ClassName that will add or remove a class name from any object like the input tag. You could just set the className of the object and then delete it when done, but the ClassName object allows for multiple classes to be set on the input tag.
ClassName = {
add: function (obj, clsName) {
if(!ClassName.exists(obj,clsName)) obj.className+=obj.className?' '+clsName:clsName;
},
remove: function (obj, clsName) {
obj.className=obj.className.replace(obj.className.match(' '+clsName)?' '+clsName:clsName,");
},
exists: function (obj, clsName) {
return new RegExp('\\b'+clsName+'\\b').test(obj.className);
}
};
The Hint object is the main object that makes everything work. It performs 5 primary functions. It initializes all input tags that have the hintvalue attribute set with an onFocus and onBlur event to show or hide the hint. When the form is submitted, any hints will be removed so the server gets the intended value. There is also a function to dynamically attach an event to any html/dom object.
Hint = {
cls_name: "hint_display",
attr_name: "hintvalue",
show: function (inputObj) {
if (inputObj.target) inputObj = inputObj.target;
else if (inputObj.srcElement) inputObj = inputObj.srcElement;
if (inputObj.value.length == 0) {
ClassName.add(inputObj, Hint.cls_name);
inputObj.value = inputObj.getAttribute(Hint.attr_name);
}
},
hide: function (inputObj) {
if (inputObj.target) inputObj = inputObj.target;
else if (inputObj.srcElement) inputObj = inputObj.srcElement;
if (ClassName.exists(inputObj, Hint.cls_name)) {
if (inputObj.getAttribute(Hint.attr_name) == null) {
inputObj.setAttribute(Hint.attr_name, inputObj.value);
}
inputObj.value = "";
}
ClassName.remove(inputObj, Hint.cls_name);
},
submit: function () {
tags = document.getElementsByTagName("INPUT");
//submit: function (formObj) {
//tags = formObj.getElementsByTagName("INPUT");
for (var i = 0; i < tags.length; i++) {
if (ClassName.exists(tags[i], Hint.cls_name)) tags[i].value = "";
}
},
listen: function(element, evtName, funcPtr) {
if (typeof element == 'string')
element = document.getElementById(element);
if (element.addEventListener) {
element.addEventListener(evtName, funcPtr, false);
} else if (element.attachEvent) {
element.attachEvent('on'+evtName, funcPtr);
} else return false;
return true;
},
init: function(parentObj) {
//if (parentObj == null) parentObj = document;
parentObj = document;
var tags = parentObj.getElementsByTagName("INPUT");
for (var i = 0; i < tags.length; i++) {
if (tags[i].getAttribute(Hint.attr_name) != null) {
hintval = tags[i].getAttribute(Hint.attr_name);
if (tags[i].value == hintval || tags[i].value == "") {
tags[i].value=hintval;ClassName.add(tags[i], Hint.cls_name);
} else
ClassName.remove(tags[i], this.cls_name);
// Now add the events
if (!Hint.listen(tags[i], 'blur', Hint.show) ||
!Hint.listen(tags[i], 'focus', Hint.hide)) {
// if we can't add the events, no hints.
tags[i].value="";
ClassName.remove(tags[i], Hint.cls_name);
}
}
}
for(j=0; j<document.forms.length; j++) {
Hint.listen(document.forms[j], 'submit', Hint.submit);
}
}
};
Finally, call the hint initialization when the page is fully loaded and add any styles to make the boxes and text display like you want them to.
Hint.listen(window, 'load', Hint.init);
/* css styles */
/* What will the hint text look like? This will make it gray */
.hint_display {color:#666666}
/* Now, make the the search box have small text and a blue border */
.smallbox {font-size:70%;border-color:blue;}
A Little Explanation
After more than a year of absolutely positioning divs to put the hint text above a text box and dealing with all the cross browser issues that came with that, not to mention more markup and quite a bit of time, I finally resorted to changing the value of the text box to show the hint and just add a class to allow it to look like a hint.
This has solved all positioning problems associated with the divs approach. The only problems now are that you cannot use an image as the hint like this website and the hint must be hidden when the form is submitted. Not much can be done about the images and that is not a big problem for me. As for the submitting issue, I have added an event to each form to remove the hint text when the form is submitted. So, why is that a problem? Some forms are submitted through a custom function and sometimes ajax is used to validate form fields on the fly. These will still work, but care must be taken to capture the value correctly. I.e. If ajax also validates a field on the onBlur event, that listener must be registered before the hints onBlur event.
Put it all together
Include the following javascript file in your web page and add the hintvalue attribute to your input tag and you are ready to go.
Javascript
See the full example here: HTML Example
Conclusion
This is a very simple and easy to use set of functions to provide a fully functional hint and any input field. Give it a try.
Challenge to anyone who wants to try: Because of the events added to form fields and the form itself, an excellent extension to this would be to add a validate attribute to the field that would act as a regular expression to check in the onBlur.
Any takers?