Form Input Example Plugin

Rob Loach's picture
  1. /*
  2. * jQuery Example Plugin 1.2.1
  3. * Populate form inputs with example text that disappears on focus.
  4. *
  5. * e.g.
  6. *  $('input#name').example('Bob Smith');
  7. *  $('textarea#message').example('Type your message here', {
  8. *    class_name: 'example_text',
  9. *    hide_label: true
  10. *  });
  11. *
  12. * Copyright (c) Paul Mucur (http://mucur.name), 2007-2008.
  13. * Dual-licensed under the BSD and GPL Licenses (LICENSE.txt).
  14. *
  15. * This program is free software; you can redistribute it and/or modify
  16. * it under the terms of the GNU General Public License as published by
  17. * the Free Software Foundation; either version 2 of the License, or
  18. * (at your option) any later version.
  19. *
  20. * This program is distributed in the hope that it will be useful,
  21. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  23. * GNU General Public License for more details.
  24. */
  25. (function($) {
  26.      
  27.   $.fn.example = function(text, args) {
  28.    
  29.     /* Load the default options. */
  30.     var options = $.extend({}, $.fn.example.defaults, args);
  31.    
  32.     /* The following event handlers only need to be bound once
  33.      * per class name. In order to do this, an array of used
  34.      * class names is stored in the document body and is checked
  35.      * on each use of the plugin. If the class name is in the
  36.      * array then this whole section is skipped. If not, the
  37.      * events are bound and the class name added to the array.
  38.      */
  39.     var bound_class_names = $.fn.example.bound_class_names;
  40.    
  41.     if ($.inArray(options.class_name, bound_class_names) == -1) {
  42.      
  43.       /* Because Gecko-based browsers "helpfully" cache form values
  44.        * but ignore all other attributes such as class, all example
  45.        * values must be cleared on page unload to prevent them from
  46.        * being saved.
  47.        */
  48.       $(window).unload(function() {
  49.         $('.' + options.class_name).val('');
  50.       });
  51.      
  52.       /* Clear fields that are still examples before the form is submitted
  53.        * otherwise those examples will be sent along as well.
  54.        */
  55.       $(this).parents('form:first').submit(function() {
  56.         $('.' + options.class_name).val('');
  57.       });
  58.      
  59.       /* Add the class name to the array. */
  60.       bound_class_names.push(options.class_name);
  61.       $.fn.example.bound_class_names = bound_class_names;
  62.     }
  63.    
  64.     return this.each(function() {
  65.       var $this = $(this);
  66.  
  67.       /* Initially place the example text in the field if it is empty. */
  68.       if ($this.val() == '') {
  69.         $this.addClass(options.class_name);
  70.         $this.val(text);
  71.       }
  72.  
  73.       /* If the field is a password field, set it to a text field while unfocused
  74.        * so the example text does not get replaced with asterisks. Add the class
  75.        * 'jquery-example-password' so we know later that the field used to be a
  76.        * password field, and it can be converted back.
  77.        */
  78.       if ($this.is(':password')){
  79.         $this.attr('type', 'text');
  80.         $this.addClass('jquery-example-password');
  81.       }
  82.  
  83.       /* If the option is set, hide the associated label (and its line-break if it
  84.         * has one).
  85.         */
  86.       if (options.hide_label) {
  87.         var label = $('label[@for=' + $this.attr('id') + ']');
  88.         label.next('br').hide();
  89.         label.hide();
  90.       }
  91.    
  92.       /* Make the example text disappear when someone focuses.
  93.        *
  94.        * To determine whether the value of the field is an example or not,
  95.        * check for the example class name only; comparing the actual value
  96.        * seems wasteful and can stop people from using example values as real
  97.        * input.
  98.        */
  99.       $this.focus(function() {
  100.         if ($(this).is('.jquery-example-password')) {
  101.           $this.attr('type', 'password');
  102.         }
  103.         if ($(this).is('.' + options.class_name)) {
  104.           $(this).val('');
  105.           $(this).removeClass(options.class_name);
  106.         }
  107.       });
  108.    
  109.       /* Make the example text reappear if the input is blank on blurring. */
  110.       $this.blur(function() {
  111.         if ($(this).val() == '') {
  112.           if ($(this).is('.jquery-example-password')) {
  113.             $this.attr('type', 'text');
  114.           }
  115.           $(this).addClass(options.class_name);
  116.           $(this).val(text);
  117.         }
  118.       });
  119.     });
  120.   };
  121.  
  122.   /* Users can override the defaults for the plugin like so:
  123.    *
  124.    *   $.fn.example.defaults.class_name = 'not_example';
  125.    *   $.fn.example.defaults.hide_label = true;
  126.    */
  127.   $.fn.example.defaults = {
  128.     class_name: 'example',
  129.     hide_label: false
  130.   };
  131.  
  132.   $.fn.example.bound_class_names = [];
  133.  
  134. })(jQuery);