jQuery tutorial: Text box hints
Updated March '08: I've separated the plugin to a separate jquery.hint.js file and included a fix to get around Firefox's autocomplete
You will see a lot of web sites with search boxes have text already populated inside of the field and when you select the input text box it disappears and reappears when it’s not selected.
This tutorial will show you how can add a small amount of jQuery to add this feature to any of your web sites.
The Goal
- To create a jQuery plugin.
- Show a ‘hint’† inside the input box when it is not in focus†† (aka blurred).
- Hide the hint when the text input has focus.
† The hint is what I am calling the text that appears and disappears within the input box.
†† Focus is the term (in this case) to indicate the user’s cursor is in the text field. Blurred is the opposite.
Demo
Our demo shows a input box for a finance web site that allows the user to search by company name or by the symbol (ticker).
How it will work
- We are going to get the hint from the ‘title’ attribute of the input box.
- When the input box has focus we will hide the hint - only if the text in the input box matches the title attribute.
- When the input box is blurred, and it doesn’t contain any text, we will show the text again.
- If the input box is blurred and does contain text, we won’t do anything.
Unobtrusive JavaScript
The first step is to design the HTML so that it will work sensibly without JavaScript turned on, i.e. we’re not going to put our hint in the input box. Since we are planning to put the hint in the title tag we’re set to code.
The Code
HTML
<form action="">
<div><label for="search">Search:</label>
<input type="text" name="seach" value="" id="search" title="Company name or ticker" />
<input type="submit" value="Go" />
</div>
</form>
Pretty simple - nothing unexpected there.
jQuery Plugin
jQuery.fn.hint = function (blurClass) {
if (!blurClass) {
blurClass = 'blur';
}
return this.each(function () {
// get jQuery version of 'this'
var $input = jQuery(this),
// capture the rest of the variable to allow for reuse
title = $input.attr('title'),
$form = jQuery(this.form),
$win = jQuery(window);
function remove() {
if ($input.val() === title && $input.hasClass(blurClass)) {
$input.val('').removeClass(blurClass);
}
}
// only apply logic if the element has the attribute
if (title) {
// on blur, set value to title attr if text is blank
$input.blur(function () {
if (this.value === '') {
$input.val(title).addClass(blurClass);
}
}).focus(remove).blur(); // now change all inputs to title
// clear the pre-defined text when form is submitted
$form.submit(remove);
$win.unload(remove); // handles Firefox's autocomplete
}
});
};
Here’s a breakdown of some of what’s going on:
return this.each(function() {
Ensure we are applying the plugin to all the matched elements and allowing our plugin to be chained.
var $input = jQuery(this)
Creating a cached copy of the jQuery object so we can use jQuery’s functions for testing, without the overhead of continuously making new jQuery objects.
We're using a $ symbol as a prefix to the variable to give a visual que that the variable contains jQuery functions, rather than a plain DOM element.
$input.blur(function(){
When the element loses focus - execute the function that has been passed in. In our case, we are testing whether the field has been left blank, and if it has - we set it to the title attribute (cached earlier).
We are also adding a class called ‘blur’ to the input box so as to give the user the impression that the text that appears in the box has not been entered by them. Note that we remove this class when the element takes focus.
$input.blur()
We end up with a final call to the blur method - so that all the matched elements are set by default as blurred (i.e. with the title attribute appearing in the text already).
If you’re curious, you can read more about writing jQuery plugins.
Where to take it next
Within the plugin, you could add better validation to ensure we are only applying to input elements where type is ‘text’.
Update June '07: You can view and use the label over plugin for an accessible version of the 'text hints'
There are a couple of places you could look at to improve the plugin. The first that I can think of is to apply the label element to float inside the element (as seen on Digg’s search and explained over at A List Apart: Making Compact Forms More Accessible).
The second upgrade you could make would whether you can use this kind of plugin for a select input type. I haven’t thought it through, but it could be interesting.
Let me know if you have any comments or need to point out any errors.
You should follow me on Twitter here I'll tweet about JavaScript, HTML 5 and other such gems (amongst usual tweet-splurges)
So I am completely new to javascript so I am somewhat lost. What I did was create the test file that was given above.
and the jquery listed above in a seperate file..jquery.js
However when I did this all I got was the normal text box; no hint inside. Please view at link listed below.
I know there must be more to this, but I have no idea how to get it to work. I uploaded all of it at: http://www.lastoptionmedia.com/test.html and the jquery file is at: http://www.lastoptionmedia.com/jquery.js, if you would like to take a look at either of those.
Any help would be greatly appreciated!
Thank you,
Brandon Hempel
A wonderful plugin, Remy. One use case I can't figure out: go to your demo page, type some text, and hit 'Go'. Now click the back button in your browser. The hint does show/hide as it is supposed to. Not major, but something I can't figure out. Jason
awesome, tried out this plugin and it works perfect with no problems! just leaving my thanks.
Thanks from me too - it seems like every time I go looking for a jQuery script I find lots of options but I usually find exactly the functionality I'm looking for on your site...
Love your plugin!
However, one question... Has anyone used this with ASP.NET? I'm trying and it seems that ASP.NET's built in form submission does not respect this plugin trying to clear out the hint text before submitting.
$form.submit(remove);
...never gets fired before ASP.NET does its postback...
Thanks for any advice.
Thanks for this tutorial, exactly what I was looking for!
I tried the jquery.hint.js file and it worked great except that the auto-complete fix and clearing pre-defined text was not working for me until I changed the remove function. I only had to change this.value to $input.val()
Thanks!
Very nice plugin and got it working quickly. The only issue I'm a bit challenged by is how I use it on a input box with where type="password" and where I'd like to show the word "password" instead of the bullets. Can anyone provide a solution?
Just wanted to say thanks for the plugin, I love it and am using it on a few different websites for the college I work for.
Great plugin, it does not work with jQuery 1.3 though. Here is the fix:
t.parents("form:first()").submit(function(){should be:
t.parents("form:first").submit(function(){Enjoy.
@Ferdy - you're right - that was some old code, though the link to the plugin was updated some time ago and it doesn't actually use the selector to get the form. It uses
this.formwhich I think is much more succinctNone the less, I'll have to update the code in the tutorial - thanks!
@Remy,
Link to the plugin? Ahem, didn't even see that. I just copied and pasted the code straight from this page to a new js file. My bad.
Same issue with the password here in a typical login form. How can you make this work?
@Remy
Not sure if this is a bug, but it happens on your demo too:
When you click the browser's reload, the title becomes a "static" value rendering the function broken. I'm using FF 3.0.5 on MacOS 10.5.5
Thanks for this -- it was very useful. I ended up porting the logic to YUI 3, for use in an app.
Clear the input value if it's the same as title before submiting the form
@FDisk - You don't need the
$form.bind('submit', remove);as it's the same as$form.submit(remove);- otherwise, nice catch on the remove function - I'll update the script.For those asking about how to do it for passwords, you can have an input type="text" to begin with, and on focus you can switch it out for an input type="password" and then if they don't type stuff in it, go back to input type="text" afterwards. we currently use this technique here: http://www.allyearbooks.co.uk/yearbooks ... however, one downside is that now even if my browser 'remembers' the username or password, giving the hint means I need to type them both again every time
any solution to this?
I'm having the same problem as k00k; Firefox 3.0.6 Mac on OS X 10.5.6 will render the text in the box as regular selectable text (just as if it were the value already typed in the box) if you press "reload". If you select that text, delete it, then click outside the box, the hint text reappears correctly. Hope this can be fixed, as I've started to use this code in several websites!
Hey guys m getting error at following statement
if ($input.val() === title && $input.hasClass(blurClass)) {
Saying "The entity name must immediately follow '&' in entity reference"
I am trying above code in Visual web JSF. Please help me out.