Unobtrusive “clear searchfield on focus”

A very common yet annoying task in daily webdeveloping is to clear the text displayed in a search field, when the field is focused. And even better, the text should be restored when the user leaves the input field empty.

The naive approach uses inline onblur and onclick javascript, or maybe at least onblur and onfocus (handles both keyboard and mouse navigation). The inline script then checks for a certain value on focus, and deletes it, and restores that value on blur when the field is empty. Problematic is the hardcoded value: Once someone feels like the default value of the field should display something more helpful, the scripts have to be fixed, too.

At least this approached was used on this site for quite a long time. While I could blame the author of the original wordpress theme used here (or my lack of knowledge about DOM and JavaScript at that time), I’m trying to improve things, and share it.

So I went ahead, removed that ugly inline script, and added a bit jQuery magic:

$("#s").focus(function() {
	if( this.value == this.defaultValue ) {
		this.value = "";
	}
}).blur(function() {
	if( !this.value.length ) {
		this.value = this.defaultValue;
	}
});

The important idea here is to use “defaultValue”, as it provides the value as seen in the HTML markup, rather then the value entered by the user. So no matter what actual value is provided in the markup, the script works as intended. I’d call that “unobtrusive”.

While having unobtrusive scripts is great, reusing those scripts is even better. jQuery to the rescue, once more!

$.fn.search = function() {
	return this.focus(function() {
		if( this.value == this.defaultValue ) {
			this.value = "";
		}
	}).blur(function() {
		if( !this.value.length ) {
			this.value = this.defaultValue;
		}
	});
};
$("#s").search();

The transfer from a plain script to a reuseable plugin could hardly be any easier. The plugin is named “search”, contains nearly the same code as above, and is then applied to the search field (selected via id).

A confusing thing may be the use of “this”. Inside the plugin function, “this” refers to the jQuery object, here an object that wraps the input field with the idea “s”. The Firebug console would display it as “[input#s search]”. Square brackets because a jQuery object is, or rather pretends to be, an array, type of “input”, id of “s”, name of “search”.

Inside the two event handlers for “focus” and “blur”, “this” refers to the DOM element. Plain JavaScript events behave the same, therefore jQuery adopted that style of scope. In this case it is quite handy, because we can access both value and defaultValue properties directly.

Of course our last, or maybe even our first step should be to check if browsers really support both properties used here. To my humble knowledge, this is the case, and we don’t have to worry about any IE inconsistencies or Safari memory problems.

-Jörn

No more comments.
  1. excellent. thank you.

  2. if( !this.value.length ) is clever. I have similar idea here http://js-playground.blogspot.com/2006/06/clear-all-inputs-value-on-focus.html that one don’t need jquery

  3. Looks like you beat me to the punch – I was writing practically the same tutorial on my web site that I delayed publishing last night!

    http://remysharp.com/2007/01/25/jquery-tutorial-text-box-hints/

    I think the very best practise is actually to use the label element over the input box – but that’s another tutorial.

  4. Yep, the A List Apart technique is even better. That one would actually make more sense as a plugin.

  5. Jernej

    Thanks! Extacly what I needed.

  6. strangethingintheland

    This was exactly what I was looking for. Thanks.

  7. While this is excellent javascript, I have one comment.

    You’re using it as a function in the second example to reuse on a page, but then why are you still searching for an ID, and not a class?

  8. @Connor: The last line in the example shows the usage. Put the function into some library file, and use it elsewhere as you need it.

  9. Anonymous

    Very Nice utility snippet. Though the needs are slightly different but this can be used.
    Raj

  10. Anonymous

    Quick question.
    I wanted to use something like this for someone to enter a donation or a price for a product, etc.

    How would I go about having it so when the user clicks on it the default value disappears and leaves only a dollar symbol?

    If I do this.value = “$”; then the .blue() function doesn’t kick in because obviously it does now have a value.

    How would I word the .blur() if statement so that if it’s empty or if it only has a dollar symbol it will go back to default?

  11. Anonymous

    Nevermind, I figured it out.

    $(“#s”).focus(function() {
    if( this.value == this.defaultValue ) {
    this.value = “$”;
    }
    }).blur(function() {
    if( !this.value.length || this.value == “$” ) {
    this.value = this.defaultValue;
    }
    });

  12. emptywalls

    Thanks very much for this. I am doing the javascript replacement with jquery on the new company site, and this is exactly what I needed.

  13. Dagomar

    That is a lifesaver! Took me about 5 minutes to implement this on a Drupal site! Thanks!

  14. ana

    Great script! Very useful for a jquery dummy 🙂

  15. midday

    >>works_as_espected?
    =>true

    thanks 🙂

  16. ravi

    thanks a lot i tried it. works perfectly 😀

  17. Thanks for posting this! I’m a jQuery beginner and this was exactly what I needed :).