Unobtrusive “clear searchfield on focus”
23. January 2007 at 22:59 by Jörn Getting Started,jQuery

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. 24. January 2007 |18:42

    excellent. thank you.

  2. 25. January 2007 |07:10

    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. 25. January 2007 |16:06

    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. 25. January 2007 |16:28

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

  5. Jernej
    17. June 2008 |09:30

    Thanks! Extacly what I needed.

  6. strangethingintheland
    29. November 2008 |03:11

    This was exactly what I was looking for. Thanks.

  7. 3. January 2009 |04:29

    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. 3. January 2009 |13:54

    @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
    13. January 2009 |09:20

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

  10. Anonymous
    30. January 2009 |21:43

    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
    30. January 2009 |21:47

    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
    30. June 2009 |20:51

    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
    9. July 2009 |17:29

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

  14. ana
    12. July 2009 |20:21

    Great script! Very useful for a jquery dummy :)

  15. midday
    3. September 2009 |11:15

    >>works_as_espected?
    =>true

    thanks :)

  16. ravi
    20. January 2010 |13:03

    thanks a lot i tried it. works perfectly :D

  17. 31. January 2010 |01:09

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