Owlcarousel2: `replace.owl.carousel` should accept an options object to reset the carousels options

Created on 15 Jul 2015  路  5Comments  路  Source: OwlCarousel2/OwlCarousel2

When triggering replace.owl.carousel to change all the content of a carousel, we should be able to an options object that contains new options for the carousel. This could happen two different ways:

  • Adding a third parameter to the trigger call with an options object
$('.owl-carousel').trigger('replace.owl.carousel', '<div class="owl-item">Content</div><div class="item">More Content</div>', { loop: false });
  • Function overloading -- we could use the type of psuedo-function overloading that is common in JavaScript, where we check if the first argument is markup or an object. This would allow us to continue with the current pattern or the newer, more powerful pattern with new options:
// Old pattern
$('.owl-carousel').trigger('replace.owl.carousel', '<div class="owl-item">Content</div><div class="item">More Content</div>');

// New pattern
$('.owl-carousel').trigger('replace.owl.carousel', {
  markup: '<div class="owl-item">Content</div><div class="item">More Content</div>',
  options: { loop: true }
});

In addition, we currently have to manually trigger refresh.owl.carousel. We should change this so that the refresh method is called by the replace method so that we don't have to trigger this additional event.

$('.owl-carousel')
    .trigger('replace.owl.carousel', '<div class="owl-item">Content</div><div class="item">More Content</div>')
    .trigger('refresh.owl.carousel');

to just:

$('.owl-carousel').trigger('replace.owl.carousel', '<div class="owl-item">Content</div><div class="item">More Content</div>');
If you are interested in implementing this, please reply here and let us know!
approved for development feature request help wanted

Most helpful comment

Tempus35
Actually - not. I've implemented it in my Carousel and it's not working. Mainly because nothing is passed to options. The function call doesn't expect second (third) parameter.

Also somewhere between .trigger and Owl.prototype.replace something strange happens with the "content", and it always ends as domnode... No matters if this is jQuery object passed in trigger or String.

Because of that I had very hard time to figure out, how to pass options to Owl.prototype.replace, and came with it:

/* file */
...
let data = $('<div></div>'); // dataholder
let stringOfElements = '<div class="new-item">Hi, I'm centered!</div>';
let options = { center : true };
data.data( 'owl', true );
data.data( 'elements', stringOfElements );
data.data( 'options', options ); 
this.$owl.trigger( 'replace.owl.carousel', data );
this.$owl.trigger( 'refresh.owl.carousel' );
...

/* Owl */
Owl.prototype.replace = function(content) {
        this.$stage.empty();
        this._items = [];

        let contentjQ = $(content);
        if(contentjQ.data('owl'))
        {
            let options = contentjQ.data('options');
            content = contentjQ.data('elements');
            this.options = $.extend({}, this.options, options);
        }
                ...

This is a hackish workaround solution for people like me, who hate the idea of "destroying and recreating" only to change options.

All 5 comments

amazing, i need that!
any news?

Would that not be as simple as

Owl.prototype.replace = function(content, options) {
        this.$stage.empty();
        this._items = [];

        if(options){
            this.options = $.extend({}, Owl.Defaults, options);
        }

        if (content) {
            content = (content instanceof jQuery) ? content : $(content);
        }

        if (this.settings.nestedItemSelector) {
            content = content.find('.' + this.settings.nestedItemSelector);
        }

        content.filter(function() {
            return this.nodeType === 1;
        }).each($.proxy(function(index, item) {
            item = this.prepare(item);
            this.$stage.append(item);
            this._items.push(item);
            this._mergers.push(item.find('[data-merge]').andSelf('[data-merge]').attr('data-merge') * 1 || 1);
        }, this));

        this.reset(this.isNumeric(this.settings.startPosition) ? this.settings.startPosition : 0);

        this.invalidate('items');

        this.refresh();
    };

Tempus35
Actually - not. I've implemented it in my Carousel and it's not working. Mainly because nothing is passed to options. The function call doesn't expect second (third) parameter.

Also somewhere between .trigger and Owl.prototype.replace something strange happens with the "content", and it always ends as domnode... No matters if this is jQuery object passed in trigger or String.

Because of that I had very hard time to figure out, how to pass options to Owl.prototype.replace, and came with it:

/* file */
...
let data = $('<div></div>'); // dataholder
let stringOfElements = '<div class="new-item">Hi, I'm centered!</div>';
let options = { center : true };
data.data( 'owl', true );
data.data( 'elements', stringOfElements );
data.data( 'options', options ); 
this.$owl.trigger( 'replace.owl.carousel', data );
this.$owl.trigger( 'refresh.owl.carousel' );
...

/* Owl */
Owl.prototype.replace = function(content) {
        this.$stage.empty();
        this._items = [];

        let contentjQ = $(content);
        if(contentjQ.data('owl'))
        {
            let options = contentjQ.data('options');
            content = contentjQ.data('elements');
            this.options = $.extend({}, this.options, options);
        }
                ...

This is a hackish workaround solution for people like me, who hate the idea of "destroying and recreating" only to change options.

@soanvig, your workaround works perfect! Thanks!

Yes, but it is a bit dirty :P

Was this page helpful?
0 / 5 - 0 ratings

Related issues

hopea114y picture hopea114y  路  3Comments

SimonHarte picture SimonHarte  路  3Comments

Uranbold picture Uranbold  路  3Comments

SoufianeAbid picture SoufianeAbid  路  3Comments

JezCheese picture JezCheese  路  3Comments