Tutorial :jquery plugin custom methods



Question:

I am trying to build my first jquery plugin, it basically creates a button from div with mouse over/click states etc, the following code works for the basic button, however I want to create a highlight method to assign a class to replace the 'normal' class. The method gets called however I cant seem to read the options? Also if I assign the class name (addClass) by hardcoding it, I seem to lose the mouse event for the over and click states?

The code:

(function(jQuery) {  jQuery.fn.divbutton = function(options)       {          // default settings          var options = jQuery.extend(          {              width: '75px',                                  // button width              height: '25px',                                 // button height              normal_class: 'brighterbutton',                 // normal state class              highlight_class: 'brighterbutton-highlight',    // normal state class              mouseover_class: 'brighterbutton-mouseover',    // mouseover class              mousedown_class: 'brighterbutton-mousedown',    // mousedown class              highlighted: false          },          options);      this.each(function()       {          jQuery(this).addClass(options.normal_class);          jQuery(this).width(options.width);          jQuery(this).height(options.height);            jQuery(this).mouseover(function() {              jQuery(this).addClass(options.mouseover_class);          });            jQuery(this).mouseout(function() {              jQuery(this).removeClass(options.mouseover_class);              jQuery(this).removeClass(options.mousedown_class);          });            jQuery(this).mousedown(function() {              jQuery(this).addClass(options.mousedown_class);          });            jQuery(this).mouseup(function() {              jQuery(this).removeClass(options.mousedown_class);          });      });        // public methods      this.doHighlight = function()       {          alert("this doesnt get called");          return this;      };        return this;  };        jQuery.fn.highlight = function()   {      alert("this gets called");        return this.each(function()       {          //this.removeClass(this.options.normal_class);          //this.addClass(this.options.highlight_class);      });  };    })(jQuery);  


Solution:1

I'm not sure exactly what it is you're trying to achieve - could you elaborate on what the purpose doHighlight() will be?

You can extend $.fn inside of another plugin such that the inner plugin can only be used when the outer plugin is used. For example,

Working Demo - add /edit to the URL to see the code

CSS colours used in demo

.brighterbutton { background-color: yellow; }  .brighterbutton-highlight { background-color: red; }  .brighterbutton-mouseover { background-color: orange; }  .brighterbutton-mousedown { background-color: purple; }  

and the code

    (function($) {            $.fn.divbutton = function(options)               {                  // default settings                  var settings = $.extend(                  {                      width: '75px',                                  // button width                      height: '25px',                                 // button height                      normal_class: 'brighterbutton',                 // normal state class                      highlight_class: 'brighterbutton-highlight',    // normal state class                      mouseover_class: 'brighterbutton-mouseover',    // mouseover class                      mousedown_class: 'brighterbutton-mousedown',    // mousedown class                      highlighted: false                  },                  options||{});              this.each(function()               {                  var $this = $(this);                    $this.addClass(settings.normal_class);                  $this.width(settings.width);                  $this.height(settings.height);                    $this.mouseover(function() {                      $this.addClass(settings.mouseover_class);                      $this.doHighlight(); // call inner plugin                  });                    $this.mouseout(function() {                      $this.removeClass(settings.mouseover_class);                      $this.removeClass(settings.mousedown_class);                  });                    $this.mousedown(function() {                      $this.addClass(settings.mousedown_class);                  });                    $this.mouseup(function() {                      $this.removeClass(settings.mousedown_class);                  });              });                // inner plugin that can be used only when               // divbutton plugin has been used              $.fn.doHighlight = function()               {                  $this.addClass(settings.highlight_class);              };                return this;          };        })(jQuery);    I don't know whether this is good practice. The inner plugin does have access to the outer plugin's settings object however.  

EDIT:

Here's one way in which you could handle it - this is an elaboration of the comments

(function($) {  $.fn.divbutton = function(options)       {          // default settings          options = $.extend(          {              // it might be easier to pass an object               // to jQuery's css command              css: {         width : '75px',                                         height: '25px',                             'text-align': 'center'                   },                                           standardClass: 'brighterbutton',                          saveClass:     'brighterbutton-highlight',                overClass:     'brighterbutton-mouseover',                downClass:     'brighterbutton-mousedown',              saveButton:    false          },          options||{});            // if a saveButton is wanted, then use the save CSS class          // which can still be supplied in the options          if(options.saveButton)            options.standardClass = options.saveClass;        this.each(function()       {          var $this = $(this);            $this.addClass(options.standardClass);          $this.css(options.css);            $this.mouseover(function() {              $this.addClass(options.overClass);          });            $this.mouseout(function() {              $this.removeClass(options.overClass);              $this.removeClass(options.downClass);          });            $this.mousedown(function() {              $this.addClass(options.downClass);          });            $this.mouseup(function() {              $this.removeClass(options.downClass);          });      });      return this;  };  })(jQuery);  

Working Demo

jQuery code

$(function() {    $('div.standard').divbutton();    $('div.save').divbutton({ saveButton: true });  });  

HTML

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">  <head>  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>  <title>Sandbox</title>  <meta http-equiv="Content-type" content="text/html; charset=utf-8" />    <style type="text/css" media="screen">        body { background-color: #fff; font: 16px Helvetica, Arial; color: #000; }      .brighterbutton { background-color: yellow; }      .brighterbutton-highlight { background-color: red; }      .brighterbutton-mouseover { background-color: orange; }      .brighterbutton-mousedown { background-color: purple; }    </style>  </head>      <body>      <div style="margin:100px;">        <p>A standard button</p>        <div class="standard">Standard</div>      </div>        <div style="margin:100px;">        <p>A save Button</p>        <div class="save">Save</div>      </div>        </body>  </html>  


Solution:2

Thanks for the help everyone, I have managed to do what I started out to do, ie have a button that is "highlightable" where all the look and feel is completely set through the css classes. I do question the efficiancy of this based on my limited knowledge of jquery and not sure if chaining methods would be quicker/more efficient?

;(function(jQuery) {      jQuery.fn.brighterbutton = function(options) {          // default settings          var options = jQuery.extend(          {              width: '75px',                                              // button width              height: '25px',                                             // button height              normal_class: 'brighterbutton',                             // normal state class          mouseover_class: 'brighterbutton-mouseover',                // mouseover class          mousedown_class: 'brighterbutton-mousedown',                // mousedown class          highlight_class: 'brighterbutton-highlight',                // highlight class          highlight_mouseover: 'brighterbutton-highlight-mouseover'   // highlight mouseover class      },      options || {});        this.each(function() {          var self = jQuery(this);            self.addClass(options.normal_class);          self.width(options.width);          self.height(options.height);            self.mouseover(function() {              self.addClass(options.mouseover_class);          });            self.mouseout(function() {              self.removeClass(options.mouseover_class);              self.removeClass(options.mousedown_class);          });            self.mousedown(function() {              self.addClass(options.mousedown_class);          });            self.mouseup(function() {              self.removeClass(options.mousedown_class);          });      });        jQuery.fn.highlight = function() {          var self = jQuery(this);          return self.each(function() {              self.addClass(options.highlight_class);                self.unbind('mouseover').mouseover(function() {                  self.addClass(options.highlight_mouseover);                  self.removeClass(options.highlight_class);              });                self.unbind('mouseout').mouseout(function() {                  self.removeClass(options.mouseover_class);                  self.removeClass(options.mousedown_class);                  self.removeClass(options.highlight_mouseover);                  self.addClass(options.highlight_class);              });                self.unbind('mousedown').mousedown(function() {                  self.removeClass(options.mouseover_class);                  self.removeClass(options.highlight_mouseover);                  self.addClass(options.mousedown_class);              });                self.unbind('mouseup').mouseup(function() {                  self.removeClass(options.mousedown_class);              });            });      };        return this;  };  })(jQuery);  

Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »