views:

402

answers:

2

I created a jQuery plugin that was working great until I started testing it with more than one object on a page. The problem is that the options object passed to each new plugin object is not always the same one associated with that specific object when I access it from inside a function in the plugin. I have a feeling that I am missing something very simple, so the code might make things more clear.

Method used to create the plugin

$.fn.myPlugin = function(options) {
    return this.each(function() {
        var opts = $.extend({}, $.myPlugin.defaults, options);
        new $.myPlugin($(this), opts);
    });
}

Function that accesses the options object

$.myPlugin = function($textbox, options) {
    function doSomething($textbox) {
        alert(options.someProperty);
    }
}

No matter what options.someProperty was when I created the plugin. The call to doSomething inside the plugin will always return the someProperty of the first options object in the first plugin object I created for example:

$textbox.focus(function() { doSomething($textbox); } );

This will always return the same someProperty even if different objects with different options objects are focused.

I hope I have made this clear enough. Let me know if you need anymore details.

+1  A: 

You're giving the plugin a reference to the same options object for all of the elements.

Try the following:

return this.each(function() {
    new $.myPlugin($(this), $.extend({ }, options));
});

This will copy the members of the options object to a new object each time. If your options object has other objects nested within it, you might need a deep copy, like this: $.extend(true, { }, options)

EDIT: You need to extend the options object inside the each method. Otherwise, you'll still have the same object for all of the elements.

SLaks
I was already extending the options object. Sorry I didn't include that in the code sample. Thanks for the quick response though.
I moved the extend call inside the each loop and still no luck. Anymore ideas?
A: 

Try changing

function doSomething($textbox) {

to

var doSomething = function($textbox) {

to ensure that you are creating separate doSomething methods that use separate closures. (the first version will create a single function the first time it's called, and reuse that function and its closure)

SLaks