tags:

views:

1538

answers:

3

Hi 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);
A: 

Check jQuery tutorials page. They have a bunch of Plugin Development tutorials.

Elzo Valugi
+2  A: 

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"&gt;
<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"&gt;&lt;/script&gt;
<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>
Russ Cam
Hi, Thanks for the reply,The purpose of the highlight is to highlight save buttons on a form for an application. Essentially I want to replace the "normal_class" with "highlight_class". if I add the following to the doHighlight method (code below) the button takes on the new class, however the over/down mouse events dont appear to work:jQuery(this).removeClass(options.normal_class);jQuery(this).addClass(options.highlight_class);Thanks for the reply, the changes to the settings and the doHighlight is called
Mark Redman
You could have a property on the options object to indicate saveButton - the default could be false, but if true is passed in, a different CSS class is used for normal_class
Russ Cam
Hi Russ, I just tried this, added an options.highlighted passed in on the highlight method. It seems that all the buttons then see these option and they all change? Are these options for the plugin, ie all instances on the button in this case? Still trying to get my head around jQuery.
Mark Redman
the plugin will be applied to all objects in the wrapped set therefore you have to come up with a way of applying the different options to standard and save buttons. The easiest way to do this would be to use a CSS class to obtain a wrapped set of standard buttons and apply the plugin to them and then get a wrapped set of save buttons and apply the plugin to them with saveButton set to true. There are a few ways that you can do this too - you could grab all the buttons then filter them to standard and apply the plugin then jump out to the outer set and filter bv save buttons and apply plugin
Russ Cam
A: 

Hi, 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);

Mark Redman