Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sharing settings across methods in namespaced jQuery plugin

Tags:

jquery

plugins

I'm writing a plugin and following the jQuery documentation's recommended practice http://docs.jquery.com/Plugins/Authoring when it comes to namespacing and multiple methods.

My init() takes care of merging default and custom settings using $.extend() however I can not figure out how to make those options available outside of the init() method. Say that call and initialize my plugin using

$("a").myplugin({debug:false}); 

how can I reference the debug property later when I call

$("a").myplugin("someMethod")?  

A rough example is:

   (function( $ ){
        var methods = {
            init: function(customSettings) {
                var options = {
                    debug: true
                }
                return this.each(function () {
                   if (customSettings) {
                       $.extend(options, customSettings);
                   }
                });
            },
            someMethod: function() {
               if(options.debug) { // <-- How can I access options here?
                   // do something
               }
            }
         }
    })( jQuery );

    $.fn.myplugin = function (method) {
                if (methods[method]) {
                    return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
                }
                else if (typeof method === 'object' || !method) {
                     return methods.init.apply(this, arguments);
                }
                else {
                     $.error('Method ' + method + ' does not exist on jQuery.tbwaga');
                }
            };
like image 625
tforster Avatar asked Mar 02 '11 00:03

tforster


2 Answers

I didn't look at your plugin template, but I wanted to share this jQuery plugin formatting... it adds a reverse reference to the DOM object in jQuery's stored data. This makes it very easy to access the plugin functions and/or variables even from outside of the plugin closure.

Here is a post describing the plugin structure in more detail.

So to access a function inside the plugin, you simply use the data object:

$('a').data('myplugin').function_name();

or even get a variable from the plugin settings

var height = $('a').data('myplugin').options.height;

But to answer your question, to make your options available to other functions inside the closure, just define the option variable outside of the init function:

(function( $ ){
        var options, methods = {
            init: function(customSettings) {
                options = {
                    debug: true
                }
like image 50
Mottie Avatar answered Oct 16 '22 20:10

Mottie


Like fudgy wrote you may consider setting your defaults outside the init method. I tried following that same tutorial and came up with the following code combining settings and methods, but I ran into some other disadvantage.

  (function( $ ){
     var config, methods = {
        init: function(customSettings) {
            var config = {
                debug: true
            }
            return this.each(function () {
               if (customSettings) {
                   $.extend(config, customSettings);
               }
            });
        },
        someMethod: function(arg) {
           if(options.debug) {
               // do something
               alert('debug ' + arg);
           } else {
               alert('no debug' + arg);
           }
        }
    }

    $.fn.myplugin = function (method) {
        if ( methods[method] ) {
            return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
        } else if ( typeof method === 'object' || ! method ) {
            return methods.init.apply( this, arguments );
        } else {
            $.error( 'Method ' + method + ' does not exist on jQuery.myplugin' );
        }
    };

})( jQuery );

But when your call it like:

$('p.one').myplugin({ 'debug' : 'false' });

For the second paragraph debug is unfortunately still false.

$('p.two').myplugin('someMethod', 'hmm!');

I first need to init the paragraph with 'true' again to be able to debug it.

$('p.two').myplugin({ 'debug' : 'true' });
$('p.two').myplugin('someMethod', 'hmm!');

Did I oversee something in the tutorial?

like image 21
André van Toly Avatar answered Oct 16 '22 22:10

André van Toly