I really like this approach, Scott!
The advantage it has is that it plays nicely with form validation. Not
an issue with a simple search field, but for larger forms in which the
fields need to be empty unless user enters text, the other approach
could foil validating on required fields because those fields would
have the placeholder text.
I wrote a similar plugin for a project at work. With mine, you select
the input rather than the label. It uses the label text by default,
but it can also use the input's title attribute or a custom string.
The disadvantage of mine is that it might require some additional CSS
to get the label to line up properly.
Anyway, here it is, in case anyone is interested.
(function($) {
$.fn.defaulttext = function(options) {
var elText = {
title: function(input) {
return $(input).attr('title');
},
label: function(input) {
return $('label[for=' + input.id +']').text();
}
};
var defText;
return this.each(function() {
var $input = $(this);
if (this.type === 'text' || this.nodeName.toLowerCase() ===
'textarea') {
var opts = $.extend({}, $.fn.defaulttext.defaults, options ||
{}, $.metadata ? $input.metadata() : $.meta ? $input.data() : {});
if (opts.dtText.constructor === Function) {
defText = opts.dtText(this);
} else if (opts.dtText && opts.dtText.constructor === String){
defText = (/(title|label)/).test(opts.dtText) ?
elText[opts.dtText](this) : opts.dtText;
}
if (!defText) {return;}
if ($input.parent().css('position') == 'static') {
$input.parent().css({position: 'relative'});
}
$(opts.dtTag).html(defText)
.addClass(opts.dtClass)
.css({
position: 'absolute',
top: $input.position().top,
left: $input.position().left,
display: 'none'
})
.insertBefore($input);
// hide default text on focus
$input.focus(function() {
dtHide($input);
});
$input.prev('.' + opts.dtClass).click(function() {
dtHide($input);
$input.focus();
});
// conditionally show default text on ready and input blur
dtShow($input);
$input.blur(function() {
dtShow($input);
});
}
});
function dtHide(el) {
el.prev().hide();
}
function dtShow(el) {
if ($.trim(el.val()) == '') {
el.prev().show();
}
}
};
$.fn.defaulttext.defaults = {
dtTag: '<span></span>', // this is the element used for the default
text
dtClass: 'default-text', // class applied to the default text
dtText: 'label' // 'label' uses text of input's label;
'title' uses input's title attribute.
// otherwise, use some other string or
function
};
})(jQuery);
--Karl
____________
Karl Swedberg
www.englishrules.com
www.learningjquery.com
On Jul 17, 2008, at 9:24 PM, Scott Sauyet wrote:
Andy Matthews wrote:
Is there a plugin for this by chance? I know it's pretty quick to
write, but wanted to find out if someone's already done it better
than I could.
Also, would toggle() work for this sort of thing? Is there a focus/
blur toggle in the jQuery core?
Something similar I did some time ago:
http://scott.sauyet.com/thoughts/archives/2007/03/31/overlabel-with-jquery/
(scroll to the bottom for the final version.) This places the label
for a text field on top of that box but hides it on focus or when
there is actual content in the field. It's mainly a real-estate
saving feature.
-- Scott