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.
Archived Comments
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();
Might also want to trim the val before checking length:
$.trim($(this).val()).length == 0
Using the title is a good idea.
Another option is Doug Neiner's in-field labels plugin:
http://fuelyourcoding.com/s...
May be overkill in some instances though...
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");
});
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.
@Ross: is it _wrong_ to use a title on an input? i thought that was kind of a nice thing to have for accessibility?
Ditto Todd - wouldn't title also give you mouseover support for it?
@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!
@ross: cool. i'd be interested to learn more about data() - will need to read up on that.
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...
Derek, I did mention placeholder at the end of the blog entry. :)
@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.
@Ray Yeah :), but this allows you to have cake + eat it!
@Dan: I'll change it and credit you.
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.
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,
@Danny - sorry did not paste code correctly:
$('input').each(function(){
var $this = $(this);
$this.attr('title') ? $this.attr('value', $this.attr('title')).addClass('grayText') : '';
});
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: [email protected]
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!
Yeah, I always knew about the one operator. Really.
No - I'm full of it. Dude - how cool is that!
@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.
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.)
Here's my preferred syntax <input type="text" placeholder="Default text!" name="name" />