Search code examples
meteorcarouseleachslick.js

Meteor and getting carousel to render dynamically with #each


Like slick. Struggling to get it working w/ dynamic dataset from Meteor. Problem that I now have, when opening prior instances of an item I'm left w/ ghost blank slides from priorly selected. If I open an item that has 15 images, close it and select another w/ 1 - I have 14 blank slide. Also, if I had clicked through the 15, say to the 7th slide, when I open the new item w/ 1 I'm still pointed at slide 7, which is blank, and need to click 6 slides to the left to actually see an image.

It would seem to me that I need to somehow reset the slick control? I'm just not sure where of how to do it.

Followed instructions here: Image slider doesn't show my images properly before they're cached to get up and running.

parent template

<div class="col-md-7">
  <div class="gallery">
    {{#each galleryImages}}
      {{> slickItem}}
    {{/each}}
  </div>
</div>

slick template

<template name="slickItem">
    <img class="slick-image" src="{{href}}">
</template>

I've played around w/ a few different options on the slick render.

 Template.slickItem.onRendered(function() {
    setTimeout(function() {
        $('.gallery').slick({
            arrows: true,
            dots: false,
            autoplay: false,
            infinite: true,
            mobileFirst: true,
            adaptiveHeight: true
        })
    }, 100);
});

Solution

  • Working with friend Patrick Lewis we worked out the following - done now in React versus Blaze.

    Carousel = React.createClass({

    getInitialState: function() {
        return {
              carousel : null
        }
    },
    
    componentDidMount() {
    
        console.log("componentDidMount");
    
        this.setState({
            // carousel: $('#maveletCarousel')
            carousel: $(this.props.id)
        }, function() {
            console.log("carousel: componentDidMount", this.state);
            this.state.carousel.carousel();
        });
    },
    
    initCarousel: function() {
    
        // $('#maveletCarousel').carousel();
    
        // Initialize the carousel
        if( this.state.carousel ) {
            this.state.carousel.carousel({
                interval : 2000
            });
        }
    
    },
    
    render() {
    
        var hrefId = "#" + this.props.id;
    
        // <li data-target={hrefId} key={ index } data-slide-to={ index } className={ indicatorClass }></li>
    
        return (
    
          <div id={this.props.id} className="carousel slide">
    
              <ol className="carousel-indicators">
                  {
                      this.props.slides.map((slide, index) => {
                          return (
                              <li data-target={hrefId} key={ index } data-slide-to={ index }></li>
                          );
                      })
                  }
              </ol>
    
              <div className="carousel-inner" role="listbox">
                  {
                      this.props.slides.map((slide, index) => {
                          return (
                              slide && <Slide slide={ slide } key={ index } index={ index } initCarousel={ this.initCarousel }/>
                          );
                      })
                  }
              </div>
    
              <a className="left carousel-control" href={ hrefId } role="button" data-slide="prev">
                  <span className="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
                  <span className="sr-only">Previous</span>
              </a>
              <a className="right carousel-control" href={ hrefId } role="button" data-slide="next">
                  <span className="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
                  <span className="sr-only">Next</span>
              </a>
    
          </div>
    
        );
    }
    

    });

    Slide = React.createClass({

    componentDidMount() {
        this.props.initCarousel();
    },
    
    render() {
    
        var isActive = 'item'
        if( this.props.index === 0 ) {
            isActive = 'item active'
        }
    
        return (
    
            <div className={ isActive }>
                <img src={this.props.slide.href}></img>
            </div>
    
        )
    }
    

    })