Plugins

The plugins site is currently in development.

We've been looking to provide a higher-quality, spam-free experience at the plugins site for some time, and a major error on our part forced us to shut down the current site before we could put the new one in place. We are developing a new site, and you can follow along with its development on GitHub. For more information about this transition, including steps you can take as a plugin author to prepare, please read our post about what's going on.

Doesn't work for password fields


Project:Form Example Plugin
Version:1.2.1
Component:User interface
Category:feature request
Priority:normal
Assigned:mudge
Status:closed
Description

If you try to use the current code on a password field, it will not work because the example text will simply turn into asterisks. I have made a couple changes to allow support for password fields, it all seems to work great on my site https://mypromojobs.com/sign-up

http://pb.theoverclocked.com/?diff=1228

<?php
/*
* jQuery Example Plugin 1.2.1
* Populate form inputs with example text that disappears on focus.
*
* e.g.
*  $('input#name').example('Bob Smith');
*  $('textarea#message').example('Type your message here', {
*    class_name: 'example_text',
*    hide_label: true
*  });
*
* Copyright (c) Paul Mucur (http://mucur.name), 2007-2008.
* Dual-licensed under the BSD and GPL Licenses (LICENSE.txt).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*/
(function($) {
     
  $.
fn.example = function(text, args) {
   
   
/* Load the default options. */
   
var options = $.extend({}, $.fn.example.defaults, args);
   
   
/* The following event handlers only need to be bound once
     * per class name. In order to do this, an array of used
     * class names is stored in the document body and is checked
     * on each use of the plugin. If the class name is in the
     * array then this whole section is skipped. If not, the
     * events are bound and the class name added to the array.
     */
   
var bound_class_names = $.fn.example.bound_class_names;
   
    if ($.
inArray(options.class_name, bound_class_names) == -1) {
     
     
/* Because Gecko-based browsers "helpfully" cache form values
       * but ignore all other attributes such as class, all example
       * values must be cleared on page unload to prevent them from
       * being saved.
       */
     
$(window).unload(function() {
        $(
'.' + options.class_name).val('');
      });
     
     
/* Clear fields that are still examples before the form is submitted
       * otherwise those examples will be sent along as well.
       */
     
$(this).parents('form:first').submit(function() {
        $(
'.' + options.class_name).val('');
      });
     
     
/* Add the class name to the array. */
     
bound_class_names.push(options.class_name);
      $.
fn.example.bound_class_names = bound_class_names;
    }
   
    return
this.each(function() {
      var
$this = $(this);

     

/* Initially place the example text in the field if it is empty. */
     
if ($this.val() == '') {
       
$this.addClass(options.class_name);
       
$this.val(text);
      }

     

/* If the field is a password field, set it to a text field while unfocused
       * so the example text does not get replaced with asterisks. Add the class
       * 'jquery-example-password' so we know later that the field used to be a
       * password field, and it can be converted back.
       */
     
if ($this.is(':password')){
       
$this.attr('type', 'text');
       
$this.addClass('jquery-example-password');
      }

     

/* If the option is set, hide the associated label (and its line-break if it
        * has one).
        */
     
if (options.hide_label) {
        var
label = $('label[@for=' + $this.attr('id') + ']');
       
label.next('br').hide();
       
label.hide();
      }
   
     
/* Make the example text disappear when someone focuses.
       *
       * To determine whether the value of the field is an example or not,
       * check for the example class name only; comparing the actual value
       * seems wasteful and can stop people from using example values as real
       * input.
       */
     
$this.focus(function() {
        if ($(
this).is('.jquery-example-password')) {
         
$this.attr('type', 'password');
        }
        if ($(
this).is('.' + options.class_name)) {
          $(
this).val('');
          $(
this).removeClass(options.class_name);
        }
      });
   
     
/* Make the example text reappear if the input is blank on blurring. */
     
$this.blur(function() {
        if ($(
this).val() == '') {
          if ($(
this).is('.jquery-example-password')) {
           
$this.attr('type', 'text');
          }
          $(
this).addClass(options.class_name);
          $(
this).val(text);
        }
      });
    });
  };
 
 
/* Users can override the defaults for the plugin like so:
   *
   *   $.fn.example.defaults.class_name = 'not_example';
   *   $.fn.example.defaults.hide_label = true;
   */
 
$.fn.example.defaults = {
   
class_name: 'example',
   
hide_label: false
 
};
 
  $.
fn.example.bound_class_names = [];
 
})(
jQuery);
?>

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

#1

Component:Code» User interface
Status:patch (code needs review)» active

Confirmed this works.

#2

Works with jQuery 1.1.2 and Firefox, but doesn't work on Microsoft Internet Explorer 7....

#3

Doesn't seem to work in IE 6 / jQuery 1.1.x either. Any idea what is causing the issue?

#4

Internet Explorer is the problem here! ;-)

#5

Here you go, this fixes it:

/*
* jQuery Example Plugin 1.2.1
* Populate form inputs with example text that disappears on focus.
*
* e.g.
*  $('input#name').example('Bob Smith');
*  $('textarea#message').example('Type your message here', {
*    class_name: 'example_text',
*    hide_label: true
*  });
*
* Copyright (c) Paul Mucur (http://mucur.name), 2007-2008.
* Dual-licensed under the BSD and GPL Licenses (LICENSE.txt).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*/
(function($) {

  $.fn.findPos = function(obj) {
    var curleft = curtop = 0;
       
    if (obj.offsetParent) {
      do {
curleft += obj.offsetLeft;
curtop += obj.offsetTop;
      } while (obj = obj.offsetParent);
        return [curleft,curtop];
    }
  }
     
  $.fn.example = function(text, args) {
   
    /* Load the default options. */
    var options = $.extend({}, $.fn.example.defaults, args);
   
    /* The following event handlers only need to be bound once
     * per class name. In order to do this, an array of used
     * class names is stored in the document body and is checked
     * on each use of the plugin. If the class name is in the
     * array then this whole section is skipped. If not, the
     * events are bound and the class name added to the array.
     */
    var bound_class_names = $.fn.example.bound_class_names;
   
    if ($.inArray(options.class_name, bound_class_names) == -1) {
     
      /* Because Gecko-based browsers "helpfully" cache form values
       * but ignore all other attributes such as class, all example
       * values must be cleared on page unload to prevent them from
       * being saved.
       */
      $(window).unload(function() {
        $('.' + options.class_name).val('');
      });
     
      /* Clear fields that are still examples before the form is submitted
       * otherwise those examples will be sent along as well.
       */
      $(this).parents('form:first').submit(function() {
        $('.' + options.class_name).val('');
      });
     
      /* Add the class name to the array. */
      bound_class_names.push(options.class_name);
      $.fn.example.bound_class_names = bound_class_names;
    }

  
    return this.each(function() {

      /* Initially place the example text in the field if it is empty. */
      if ($(this).val() == '') {
        $(this).addClass(options.class_name);
        if (!$(this).is(':password')){
          $(this).val(text);
        }
      }

      /* If the field is a password field, set it to a text field while unfocused
       * so the example text does not get replaced with asterisks. Add the class
       * 'jquery-example-password' so we know later that the field used to be a
       * password field, and it can be converted back.
       */
      if ($(this).is(':password')){
         var elemPosition = $(this).findPos(this);
         $(this).parent().append('<div class="' + options.class_name + '" onclick="$(this).prev().focus(); $(this).hide();">' + text + '</div>');
         $(this).next().css({
           left: elemPosition[0] + 2,
           top: elemPosition[1] + 3,
           position: 'absolute'
         });     
      }

      /* If the option is set, hide the associated label (and its line-break if it
        * has one).
        */
      if (options.hide_label) {
        var label = $('label[@for=' + $(this).attr('id') + ']');
        label.next('br').hide();
        label.hide();
      }
   
      /* Make the example text disappear when someone focuses.
       *
       * To determine whether the value of the field is an example or not,
       * check for the example class name only; comparing the actual value
       * seems wasteful and can stop people from using example values as real
       * input.
       */
      $(this).focus(function() {
        if ($(this).is(':password')){
            $(this).next().css('display', 'none');
        }
        if ($(this).is('.' + options.class_name)) {
          $(this).val('');
          $(this).removeClass(options.class_name);
        }
      });
   
      /* Make the example text reappear if the input is blank on blurring. */
      $(this).blur(function() {
        if ($(this).val() == '') {
          if ($(this).is(':password')){
            $(this).next().css('display', 'block');
          }
          $(this).addClass(options.class_name);
          if (!$(this).is(':password')){
            $(this).val(text);
          }
        }
      });
    });
  };
 
  /* Users can override the defaults for the plugin like so:
   *
   *   $.fn.example.defaults.class_name = 'not_example';
   *   $.fn.example.defaults.hide_label = true;
   */
  $.fn.example.defaults = {
    class_name: 'example',
    hide_label: false
  };
 
  $.fn.example.bound_class_names = [];
 
})(jQuery);

#6

Apologies for taking so long to follow up on this.

This is some great work, TheOverclocked, particularly with the headaches Internet Explorer caused and thanks to Rob Loach for helping to test this extension.

However, I'm not sure if I should wrap this functionality into the main plugin for a few reasons:

My goal with the plugin was to keep things as simple as possible by adding and removing styled example text in text fields on user focus and blur. Any complexity inherent in the plugin is in pursuit of making sure that this core functionality is as correct and efficient as possible (I did not anticipate the problems that browser form field caching would cause, for one thing).

The addition of changing field types (from password to text) is something I had never considered until you brought it up. From a usability perspective, I'm not sure if it confuses matter for the user: will they expect their passwords to be in clear text because the example is or will they understand that clicking changes the nature of the input? It's definitely a matter of debate which is why I have hesitated so far.

Secondly, the incompatibility with Internet Explorer has brought a brilliant but nevertheless complicated workaround requiring some serious CSS wizardry. While I am impressed with the solution, its complexity worries me.

I am, of course, open to persuasion on any of these matters. Please let it be known that I am by no means dismissing your hard work but instead wondering if such a feature is specialised and might therefore benefit from being offered as an extension or separate plugin.

Perhaps I could improve the plugin to facilitate extensions like this with callbacks?

#7

Assigned to:Anonymous» mudge
Status:active» by design

#8

Status:by design» closed

Just for future reference, it seems that changing the type of an input is not allowed in Safari either (when I tried to do so, I received the following error: "type property can't be changed").

Looking in the jQuery documentation, there is a link to a Microsoft reference article declaring the type attribute to be "read/write-once" therefore explaining the problems you encountered with IE: http://msdn2.microsoft.com/en-us/library/ms534700.aspx

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.