Fl0R1D3R
Fl0R1D3R

Reputation: 892

Extend jQuery Plugin with additional function / override function

I need to extend a jQuery Plugin (https://github.com/idiot/unslider) in order to add additional behavior with another public method.

(function(){
    // Store a reference to the original remove method.
    var originalMethod = $.fn.unslider;
    // Define overriding method.
    $.fn.unslider = function(){

        // Execute the original method.
        originalMethod.apply( this, arguments );

        console.log( "Override method" );

        function test() {
            console.log("test called");
        }

        this.each(function() {
            // Operations for each DOM element
            console.log("each dom element?");

        }).data('unslider', {
            // Make test accessible from data instance
            test: test
        });

        return this;
    }
})(jQuery);

I already managed to make the public method accessible when calling

var slider = $('#slider');
slider.data('unslider').test();

However, I want to keep the old behavior of unslider anyways, but extend the Plugin with another function. Does anyone have an idea?

I created a fiddle, so you can check whats happening: My new function gets called, but the old ones are gone: http://jsfiddle.net/b2os4s7e/1/

Upvotes: 1

Views: 1415

Answers (4)

Fl0R1D3R
Fl0R1D3R

Reputation: 892

Thanks for your answers! I did it this way:

(function($){
    var originalMethod = $.fn.unslider;

    $.fn.extend({
        unslider: function(o) {
            var len = this.length;

            var applyMethod = originalMethod.apply( this, arguments );

            var key = applyMethod.data('key');
            var instance = applyMethod.data(key);

            //  Cache a copy of $(this), so it
            var me = $(this);

            if (instance) {
                instance.movenext = function (callback) {
                    return instance.stop().to(instance.i + 1, callback);
                };
                instance.moveprev = function (callback) {
                    return instance.stop().to(instance.i - 1, callback);
                };
            }

            return applyMethod.data(key, instance);

        }
    });
})(jQuery)

The key was to address the data attribute as sroes suggested.

Moreover i needed to apply the original method, since i need the old methods.

Upvotes: 0

sroes
sroes

Reputation: 15053

If you look at the source of unslider, you can see it stores the Unslider instance inside the data:

    //  Enable multiple-slider support
    return this.each(function(index) {
        //  Cache a copy of $(this), so it
        var me = $(this),
            key = 'unslider' + (len > 1 ? '-' + ++index : ''),
            instance = (new Unslider).init(me, o);

        //  Invoke an Unslider instance
        me.data(key, instance).data('key', key);
    });

In your code you're overwriting this object with your own object. However, the slider expects there to be an Unslider instance. So what you want to do is get this instance and then extend it with your own functions:

var key = $(this).data('key');
var obj = $(this).data(key);
obj.test = function() { console.log('Working!'); };

See http://jsfiddle.net/b2os4s7e/2/

Upvotes: 1

For extend JQuery should use .fn.extend

(function($){ 
    $.fn.extend({
        helloworld: function(message){
            return this.each(function(){
                $(this).click(function(){
                    alert(message);
                });
            });
        }
    });
})(jQuery)

the object .fn.extend is used for extend funcionality of jQuery

Upvotes: 0

overburn
overburn

Reputation: 1234

Just define:

$fn.unslider2 = function() { ... } 

With any name and behaviour you like.

Upvotes: 0

Related Questions