David Kullmann
David Kullmann

Reputation: 918

jQuery scoped settings for plugin based on Plugins/Authoring article

I have a jQuery plugin which follows the Plugins/Authoring example from docs.jQuery.com and I am having trouble figuring out how to keep unique settings for each element the plugin is applied to. There are two elements on the page each having the plugin applied to them separately.

Here is my code so far:

(function( $ ) {

/* Default settings */
var defaults = {
    id: null,
    properties: null,
    container: '.comp-settings', /* override for .retail or .distressed */
    priceLabel: '.comp-section-header span',
    slide: slideCallback,
    minRange: 100000
};

/* Some public here: $.compSlider('method', options) */
var methods = {
    init: function( options ) {

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

        return this.each(function() {
            $(this).slider( settings );
        });

    }
}

/* Some methods here */
function opt( name ) {
    return settings[ name ];
}

/* Plugin namespace */
$.fn.compSlider = function( method ) {
    // Method calling logic
    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 if ( typeof method === 'string' ) {
        return this.slider( method, Array.prototype.slice.call( arguments, 1 ) );
    }
};

})( jQuery )

Issues:

  1. The settings variable isn't accessible in the plugins functions
  2. If I store the settings variable in $(this).data('settings') I still can't access $(this).data('settings') from the 'opt' function because "this" isn't the element (I believe it's the DOM window.)

Any help is appreciated.

Upvotes: 2

Views: 230

Answers (1)

uɥƃnɐʌuop
uɥƃnɐʌuop

Reputation: 15093

You can't access the settings in the compSlider function because in your example they are defined in init(), making them local to that function. If you moved the declaration up in scope:

$.fn.compSlider = function( method, options ) {
    var settings = $.extend( {}, defaults, options );
};

Then you'd be able to access it there. Or just defining it (var settings;) in compSlider and removing var in init() would be enough.

Update:

In repsonse to your comment, yes, sorry, forgot about the issue #2. As it is, you will not be able to access the settings for each plugin object because you cannot "go down" in scope. In other words, you cannot access a local variable of a function from outside of that function. And that is what settings are, local to the compSlider function (if you use the structure I proposed), they are lower in scope as far as your opt() function is concerned.

You can, of course, always go up in scope. To achieve this you could set up a variable in the plugin's global space that stores references to all objects created.

var compSliderObjects = [];

$.fn.compSlider = function( method, options ) {
    //store objects in compSliderObjects
};

However, this is just the an idea, and you still need to figure out how you want to access the compSliderObjects and pull the right settings. Will each object have a unique id? If so, an array of objects ({id: 2, settings: data}). If not, you need to figure out how you want to uniquely identify them and pull them from the array.

Also, do you really need to access them globally? It's less work and code to just call the object and get the settings (as shown in the fiddle).

Upvotes: 1

Related Questions