Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add public method to jQuery plugin based on this jQuery plugin pattern

How can I add public methods to my custom jQuery plugin which is based on this pattern from jquery-boilerplate: https://github.com/jquery-boilerplate/jquery-patterns/blob/master/patterns/jquery.extend-skeleton.js

I need to use my plugin and call public method something like this:

jQuery('.element').pluginName();

//And now assuming that plugin has a public method `examplePublicMethod`,
//I want to call it like this:
var instance = jQuery('#element').data('pluginName');
instance.examplePublicMethod();

Is it possible at all when I use this pattern from the link? Here's the code sample of this pattern:

;(function($){
    $.fn.extend({
        pluginName: function( options ) {

            this.defaultOptions = {};

            var settings = $.extend({}, this.defaultOptions, options);

            return this.each(function() {

                var $this = $(this);
                //And here is the main code of the plugin
                //...
                //And I'm not sure how to add here a public method
                //that will be accessible from outside the plugin

            });

        }

    });

})(jQuery);
like image 297
zitix Avatar asked Jun 12 '14 15:06

zitix


1 Answers

There is multiple way to do this, but the one I prefer is like that :

$.fn.extend({
    pluginName: function( options ) {

        this.defaultOptions = {};

        var settings = $.extend({}, this.defaultOptions, options);

        return this.each(function() {

            var $this = $(this);

            //Create a new Object in the data.
            $this.data('pluginName', new pluginMethods($this)) //pluginMethod are define below

        });

    }

});

function pluginMethods($el){
    //Keep reference to the jQuery element
    this.$el = $el; 
    //You can define all variable shared between functions here with the keyword `this`
}

$.extend(pluginMethods.prototype, {
    //Here all you methods
    redFont : function(){
        //Simply changing the font color
        this.$el.css('color', 'red')
    }
})


$('#el').pluginName();

//Public method:
var instance = jQuery('#el').data('pluginName');
instance.redFont();

The disadvantage with that is pluginMethods is accessible by everyone. But you can solve that by moving it in the same closure that the plugin declaration like that :

(function($){
    $.fn.extend({
        pluginName: function( options ) {

            this.defaultOptions = {};

            var settings = $.extend({}, this.defaultOptions, options);

            return this.each(function() {

                var $this = $(this);

                $this.data('pluginName', new pluginMethods($this))

            });

        }

    });

    function pluginMethods($el){
        //Keep reference to the jQuery element
        this.$el = $el; 
    }

    $.extend(pluginMethods.prototype, {
        //Here all you methods
        redFont : function(){
            this.$el.css('color', 'red')
        }
    })

})(jQuery);
like image 198
Karl-André Gagnon Avatar answered Oct 07 '22 07:10

Karl-André Gagnon