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

Reply via email to