Swiper: Dynamically loaded with blaze

Created on 21 Sep 2015  路  7Comments  路  Source: nolimits4web/swiper

Hello, Im using MeteorJS and I load my slides with a {{#each }} template helper

        <div class="swiper-container">
            <div class="swiper-wrapper">

                {{#each epis}}
                               <div class="swiper-slide">       
                    <div class="epi">   
                                             ..content here...  
                    </div> 
                                 </div>
                {{/each}}
            </div>
            <div class="swiper-pagination"></div>
        </div>

Im initializing swiper instance on onRendered callback

Template.episLista.rendered = function(){
    var swiper = new Swiper('.swiper-container', {
        pagination: '.swiper-pagination',
        slidesPerView: 3,
        slidesPerColumn: 2,
        paginationClickable: true,
        spaceBetween: 10,
    });
}

The swiper isn't loaded at all...
I think that the problem is that the HTML Layout of Swiper can't be dynamically generated.. what do you think ?

All 7 comments

You can generate Swiper content dynamically, you just need to init it when it is available in DOM

I just got this to work yesterday, in a slightly hacky way. In my case I am loading a slide for each image in my collection. The slides are contained in a modal that opens when an image is clicked on. Think Facebook.

I had the same issue until I used a setTimeout, which took care of the issue that nolimits4web pointed out. Probably not the best way, but its one of the only ways, since .onRendered() seems to run even before the DOM is ready and Blaze finished the each loop.

In my template.

<div class="swiper-container">
    <div class="swiper-wrapper">
        {{#each artworkInfo.images}}
        <div class="swiper-slide">
            <img class="img-responsive" src="{{imageURL}}">
        </div>
        {{/each}}
    </div>
    <!-- Add Pagination -->
    <div class="swiper-pagination"></div>
    <!-- Add Arrows -->
    <div class="swiper-button-next"></div>
    <div class="swiper-button-prev"></div>
</div>

In my case, in a Meteor click event

'click .show-modal': function(event) {
    $('#modal').modal('show');
    Session.set('currentArtwork', event.currentTarget.children[0].value)
    Meteor.setTimeout(() => {
        var modalSwiper = new Swiper('.swiper-container', {
            pagination: '.swiper-pagination',
            slidesPerView: 1,
            paginationClickable: true,
            spaceBetween: 30,
            keyboardControl: true,
            nextButton: '.swiper-button-next',
            prevButton: '.swiper-button-prev',
            loop: true
        })
    }, 250)
    if ($('.swiper-container')[0].swiper){
        var modalSwiper = $('.swiper-container')[0].swiper;
        modalSwiper.destroy();
    }
}

Hi! I had to time to think and made it work with a different approach, using Observe Changes, here's my code

Template.slider.onRendered(function(){
    slides = [];
    var swiper = new Swiper('.swiper-container', {
        pagination: '.swiper-pagination',
        slidesPerView: 3,
        slidesPerColumn: 2,
        nextButton: '.swiper-button-next',
        prevButton: '.swiper-button-prev',
        spaceBetween: 0,            
    })      

    Epis.observer =  Epis.find().observeChanges({
        added: function(id){            
            var epi = Epis.findOne({_id:id});
            swiper.appendSlide('<div class="swiper-slide" id="'+id+'"></div>');
            Blaze.renderWithData(Template.epiItem, {epiId:id}, document.getElementById(id))

            var obj = {
                id: id,
                slide: swiper.slides.length-1
            }
            console.log("adicionando no slide: " + parseInt(swiper.slides.length-1));
            slides.push(obj);
        },
        removed: function(id){
            console.log(_);
            var idx = -1;
            var currentSlide = _.find(slides,function(s){
                idx = idx + 1;
                return s.id==id;
            });
            swiper.removeSlide(currentSlide.slide);
            for (i=idx;i<slides.length;i++){
                slides[i].slide = slides[i].slide - 1
            }
            slides.splice(idx,1);

        },changed:function(id){

            //var epi = Epis.findOne({_id:id});
            //$("#"+id).html('');
            //Blaze.renderWithData(Template.epiItem, {epi:epi}, document.getElementById(id))
        }
    });
});

There is some code garbage here and there but you got the idea =)

Template.episLista.rendered is deprecated. You should use Template.episLista.onRendered instead. That's the reason why it doesn't get inited.

And because this is not swiper issue, I think it can be closed.

Hey guys, just use observer:true and it all will be fine =) @brandonparee

Issue is closed because of outdated/irrelevant/not actual/needed more information/inactivity.

If this issue is still actual and reproducible for latest version of Swiper, please create new issue and fill the issue template correctly:

  • Clearly describe the issue including steps to reproduce when it is a bug.
  • Make sure you fill in the earliest version that you know has the issue.
  • Provide live link or JSFiddle/Codepen or website with issue
Was this page helpful?
0 / 5 - 0 ratings

Related issues

leone510es picture leone510es  路  3Comments

voodoo6 picture voodoo6  路  3Comments

lxmarinkovic picture lxmarinkovic  路  4Comments

danielcpereira11 picture danielcpereira11  路  4Comments

nicolebo picture nicolebo  路  3Comments