Rick Liguz Rick Liguz - 27 days ago 10
jQuery Question

Jquery Plugin pattern where to place click handler

I have a web application page with several click events and I'm trying to apply the jQuery plugin pattern given below.

; (function ($, window, document, undefined) {

var Plugin = function (elem, options) {
this.elem = elem;
this.$elem = $(elem);
this.options = options;
};

Plugin.prototype = {
defaults: {
message: 'This is message'
},

init: function () {
this.config = $.extend({}, this.defaults, this.options);
var self = this;
this.selected = $('#selector');

// IS THIS THE BEST PLACE TO PUT .click EVENT HANDLERS ??
this.selected.on('click', function () {
console.log('this.selected clicked');
self.sampleMethod();
});

this.sampleMethod();
return this;
},

sampleMethod: function () {
console.log('sampleMethod');
}
};

Plugin.defaults = Plugin.prototype.defaults;

$.fn.testPlugin = function (options) {
return this.each(function () {
new Plugin(this, options).init();
});
};

})(jQuery, window, document);


My question is: I've placed the click event handlers within the init function (and they work) but is this the correct and robust place to put them?

Any help on this would be greatly appreciated.

Answer Source

I found the answer at http://markdalgleish.com/2011/05/creating-highly-configurable-jquery-plugins/ in the comments at the bottom of the article.

"Inside the init method you can set up whatever event handling logic you need."

It's a nice article that also explains how to call plugin functions from outside the plugin.

Just for completeness, and in case it helps anybody, I incorporated the article and now use this template for jQuery plugins (typically, web page plugins). It is called from the web page (using a div with id element wrapping the page html) using

$('#element').plugin_name({default_item: 'some default item'});


; (function ($, window, document, undefined) {
    "use strict";

    var plugin_name_fn = function (elem, options) {
        this.elem = elem;
        this.elemObj = $(elem);
        this.options = options;
        this.metadata = this.elemObj.data('plugin-options');
    };

    plugin_name_fn.prototype = {
        defaults: {

            default_item: ''

        },

        init: function () {
            this.config = $.extend({}, this.defaults, this.options, this.metadata);

            // Merge settings
            this.default_item = this.config.default_item;

            // Call event handlers
            this.events();

            return this;
        },

        thisFunction: function () {

            // Do something here

        },

        thatFunction: function (default_item) {

            // Do something here with default_item

        },

        events: function () {

            var self = this;
            // Events are declared and chained here
            this.elemObj
                .on('click', '#element_id', function (e) {

                    // Call thisFunction
                    self.thisFunction();

                })
                .on('change', '#another_element_id', function (e) {

                    // Call thisFunction using default_item
                    self.thatFunction(self.default_item);

                })
            ;

        }

    };

    plugin_name_fn.defaults = plugin_name_fn.prototype.defaults;

    $.fn.plugin_name = function (options) {
        return this.each(function () {
            new plugin_name_fn(this, options).init();
        });
    };

    //window.plugin_name_fn = plugin_name_fn;

})(jQuery, window, document);