ilyes kooli
ilyes kooli

Reputation: 12043

jQuery plugin chainability

I'm writing a jQuery plugin, the main aim is to take a select element and create a new component based on it, so far I just want to replace the select with an empty div:

(function($){
    $.fancySelect = {version:'1.0'};
    var methods = {
        init: function(options){
            return this.each(function(){                
                var div = $('<div></div>');
                $(this).replaceWith(div);
            });
        }
    };
    $.fn.fancySelect = function(method){
        if (methods[method]){//call a method
            return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
        } else {
             return methods.init.apply( this, arguments );
        }
    }
})(jQuery);

Trying to test, I make a simple select:

<select id="sss"></select>

When I call:

$('#sss').fancySelect();

The select is correctly replaced with an empty Div, this is Ok.
But now, when testing chainability, I try:

$('#sss').fancySelect().append('<span>new text</span>');

But my new div remain empty
So I tried:

console.log($('#sss').fancySelect());

On firebug I get:

[select#sss]

Means the plugin is returning the old select.

I tried to add

return $(this);

after

$(this).replaceWith(div);

in my plugin code, but nothing changed!

Can you please tell me what I should do to make my plugin return the fresh created Div?

Upvotes: 1

Views: 796

Answers (1)

bdukes
bdukes

Reputation: 155935

When you return this.each, you are returning the original jQuery selection, which hasn't changed even though you've replaced those elements. Instead of using each, use map to adjust what is returned:

return this.map(function(){                
    var div = $('<div></div>');
    $(this).replaceWith(div);
    return div;
});

Upvotes: 3

Related Questions