Quick jQuery Tip - Removing default search text

This post is more than 2 years old.

One of the common UI patterns is to add some default text to a search box, so for example, it may say "Enter Search" in the input field. As soon as the user clicks on the field that default text goes away. While there are probably a thousand ways of doing it, here is one quick and dirty way of doing it with jQuery.

First, ensure your search field has an ID and the default text you want.

<input type="text" name="search" id="search" value="Search for Beer!">

Next, within your document.ready block, just tell jQuery to monitor the field for clicks:

$('#searchtext').click(function() { });

As for the actual code - it is somewhat complex. You may want to move this into a separate file due to the size:

$('#searchtext').focus(function() { $(this).val("").unbind("focus"); });

Ok, sorry, I was being a bit of an ass. Basically the code says: Set the value to blank and stop listening for focus event. Nice, short, and sweet. Hope this helps.

P.S. Of course, you could just use placeholder as well: <input type="text" name="search" placeholder="Search for Beer!">. This will be ignored by browsers that don't understand it and will act like the code above for browsers that do. This works in HTML/Adobe AIR applications as well.

P.S.S. I originally used the click even - but Dan mentioned how this wouldn't work with keyboard navigation. I changed to focus based on his recommendation.

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Archived Comments

Comment 1 by todd sharp posted on 12/1/2010 at 9:34 PM

I take a bit of a "fancier" approach and use something like the title attribute for the placeholder text and put that value back in the input on blur if the user doesn't enter anything. So something like this:
$('#search').focus(function(){
if($(this).val() == $(this).attr('title')){
$(this).val('');
}
}).blur(function(){
if($(this).val() != $(this).attr('title') && $(this).val().length == 0){
$(this).val($(this).attr('title'));
}
}).blur();

Comment 2 by todd sharp posted on 12/1/2010 at 9:36 PM

Might also want to trim the val before checking length:

$.trim($(this).val()).length == 0

Comment 3 by Raymond Camden posted on 12/1/2010 at 9:37 PM

Using the title is a good idea.

Comment 4 by todd sharp posted on 12/1/2010 at 9:40 PM

Another option is Doug Neiner's in-field labels plugin:

http://fuelyourcoding.com/s...

May be overkill in some instances though...

Comment 5 by Danny posted on 12/1/2010 at 10:02 PM

I usually like to style my placeholder text to be a light gray (or whatever fits the overall style of the page) and use a class to control remove it
$(".grayText").focus(function(){ $(this).val('').removeClass("grayText");
});

I really like the idea of using the title attribute. Maybe something like this to really automate it:
on ready:
$("input").each(function(){
var theTitle = $(this).attr("title");
if (theTitle.length > 0) {
$(this).addClass("grayText");
$(this).val(theTitle);
}
});
$(".grayText").live("focus",function(){
$(this).val('').removeClass("grayText");
});

Comment 6 by Ross Pfahler posted on 12/1/2010 at 10:15 PM

I'm a big fan of using focus() over click(). I also find it a bit cleaner to use .data() over adding an attribute such as a title, especially with jQuery 1.4.3's ability to support HTML 5 data- attributes.

Comment 7 by todd sharp posted on 12/1/2010 at 10:19 PM

@Ross: is it _wrong_ to use a title on an input? i thought that was kind of a nice thing to have for accessibility?

Comment 8 by Raymond Camden posted on 12/1/2010 at 10:23 PM

Ditto Todd - wouldn't title also give you mouseover support for it?

Comment 9 by Ross Pfahler posted on 12/1/2010 at 10:31 PM

@todd: It is not wrong at all - I didn't think it through all the way. I guess the data() route would just be useful in cases when the title might be different than what was displayed as the initial value in the input. Otherwise, I think you are correct!

Comment 10 by todd sharp posted on 12/1/2010 at 10:42 PM

@ross: cool. i'd be interested to learn more about data() - will need to read up on that.

Comment 11 by Derek P posted on 12/1/2010 at 10:42 PM

placeholder attribute on input tags, in HTML5, does exactly the same thing as this JS, so in more advanced browsers you can eliminate the need for it.

I use this as a driver, coupled with modernizr, so I know I only use the JS route, on legacy browsers:

https://gist.github.com/b38...

Comment 12 by Raymond Camden posted on 12/1/2010 at 10:44 PM

Derek, I did mention placeholder at the end of the blog entry. :)

Comment 13 by Dan G. Switzer, II posted on 12/1/2010 at 11:00 PM

@Raymond:

As others have indicated in their source, avoid using the "click" event when you actually mean "focus". Your original example breaks when a user goes to use the keyboard to navigate to the form field. The click event is the correct event for things like checkboxes and radio elements, but for text fields you want to use focus.

Comment 14 by Derek posted on 12/1/2010 at 11:03 PM

@Ray Yeah :), but this allows you to have cake + eat it!

Comment 15 by Raymond Camden posted on 12/1/2010 at 11:20 PM

@Dan: I'll change it and credit you.

Comment 16 by James Moberg posted on 12/2/2010 at 12:02 AM

I've been using the jQuery Watermark library to do this:
http://code.google.com/p/jq...

It adds CSS styling for the watermark, allows you to change the watermark text/class any time after the watermark is initialized and is can display watermarks in password input elements.

Comment 17 by johans posted on 12/2/2010 at 12:22 AM

Using title makes sense. Below would work for any input, you could set the context to the container element in preference to document:

<script>
// clear input text
$(document).delegate('input', 'focus', function(){
$(this).val('');
});

// set-reset input text
$(document).delegate('input', 'blur', function(){
var $this = $(this),
val = $.trim($this.val());
$this.val(val ? val : $this.attr('title'));
});
</script>

@Danny - best to cache $(this) to a local var (var $this = $(this) in your each() loop. Also you could chain setting the title and class.
$(this,

Comment 18 by johans posted on 12/2/2010 at 12:53 AM

@Danny - sorry did not paste code correctly:

$('input').each(function(){
var $this = $(this);
$this.attr('title') ? $this.attr('value', $this.attr('title')).addClass('grayText') : '';
});

Comment 19 by Doug Neiner posted on 12/2/2010 at 5:57 AM

Hey Ray, also note if you want an event handler to fire once in jQuery, you can bind it using 'one', then you don't have to explicitly remove it:

$("#searchtext").one('focus', function () {
$(this).val("");
});

And it does just what it says, fires it once!

A couple more notes related to the comments:

The HTML5 placeholder attribute is quite different from an infield label. The placeholder is supposed to communicate the format/type of data, the label is supposed to communicate what the field is.

Label: Email address
Placeholder: you@yourname.com

Also, its important to make sure your form won't submit if it only contains the default data as you have shown here. That is one reason I prefer to use CSS + JS as Todd mentioned in my in-field labels plugin. Anyway, each situation is different!

Comment 20 by Raymond Camden posted on 12/2/2010 at 6:00 AM

Yeah, I always knew about the one operator. Really.

No - I'm full of it. Dude - how cool is that!

Comment 21 by Grant Eagon posted on 12/2/2010 at 4:23 PM

@Ray et. al

One thing I've been doing for my site is creating a "global" js file for appropriate functionality like this, so this might go in jquery.global.form.js.

In that file I would use a class instead of an id, so I can apply it to as many fields in the for as I want so something like:

$('.suggest').focus(function() {
$(this).val("").unbind("focus");
});

Then I can always rely on that functionality being there by just adding the class I need.

I end up with fields that take advantage of multiple "attribute classes":

<input
type="text"
name="beer"
value="Search Beer!"
class="suggest gray required center" />

Pretty clean way to control what each field does.

Comment 22 by Dave Anderson posted on 12/3/2010 at 1:11 AM

If you use the watermark plugin as suggested by James above, you can easily combine a couple of techniques to auto-set the 'watermark' value to the value of the title attribute, like this:
$("input.titleDefVal[title]").each(function() {
$(this).watermark($(this).attr('title'));
})
(assuming you use a class called 'titleDefVal' in the inputs you want auto-populated with the title value. change to $("input[title]").each() to do it for all inputs with a title attribute.)

Comment 23 by Drew Wells posted on 12/14/2010 at 11:03 PM

Here's my preferred syntax <input type="text" placeholder="Default text!" name="name" />