Reactive carousel help

I’m quite a newbie to web development so this might be super easy so apologies. I have db items to display in a carousel-type. I want the carousel to display the 1st 3 and then the next 3 and so on. It has to be reactive so the client can change the items whenever they want.

So, I want to use the index number. Here is my html:

<template name="carousel">
   <div class="container-fluid references-container">  
    <div class="row">
      {{#each references}}
      <div class="col-md-4">
        <div class="thumbnail" data-value="{{@index}}">
          <a class="item " href="/"><img src="{{image}}" alt="{{text}}"/></a>
              <div class="caption"> 
              <h5>{{title}} {{@index}}</h5>
              </div>
          </div>
      </div>
      {{/each}}
    </div>
  </div> 
</template>

On the page I can see the index number correctly. So, what helper should I use to loop to the next 3 index numbers?

Here’s the helper I’ve got so far:

Template.carousel.helpers({
    references:function() {
        return References.find({}, {limit:3});
    },
});

Without going into too much detail, you need to make use of the skip property:

return References.find({}, { limit:3, skip: n });

Where n is 0, 3, 6, … etc.

However, you should be aware that using skip and limit like this requires the cursor returned by find to be ordered predictably. So, for example, you add another field to your document (let’s call it sequence):

return References.find({}, { sort: { sequence: 1 }, limit:3, skip: n });

You should also add an index to sequence to improve performance of the sort operation.

1 Like

Hi Rob,

Thanks for this. Now I just need to change the display with an event as the button is clicked. Here’s the code I’ve got so far.

Helper

Template.ourReferences.helpers({
    references: function(){
        n = new ReactiveVar(0);
        return References.find({}, { sort: { sequence: 1 }, limit:3, skip: n.get()});
}});

Event

Template.ourReferences.events({
"click .js-forward":function(event){
  n.set(n.get()+1);
  console.log(n.get());
  var display = References.find({}, { sort: { sequence: 1 }, limit:3, skip: n.get()});
  console.log(display); //this comes out as undefined
  }
    
});

The problem here is that you’re not referencing the n which you defined in your helper.

What you should do is define n in the template’s onCreated and change how you reference it elsewhere:

Template.ourReferences.onCreated(function() {
  this.n = new ReactiveVar(0);
});

Template.ourReferences.helpers({
  references() {
    const templateInstance = Template.instance();
    return References.find({}, { sort: { sequence: 1 }, limit:3, skip: templateInstance.n.get()});
  }
});

Template.ourReferences.events({
  "click .js-forward"(event, templateInstance) {
    templateInstance.n.set(templateInstance.n.get()+1);
    console.log(templateInstance.n.get());
    var display = References.find({}, { sort: { sequence: 1 }, limit:3, skip: templateInstance.n.get()});
    console.log(display); //this comes out as undefined
  } 
});

You should also note that you are console.loging a cursor - which will not tell you very much. If you want to see what’s in the cursor you could use console.log(display.fetch());

1 Like

Thanks so much. I get it now. As you can tell I’m pretty new to this but I understand how this works now.

Cheers

1 Like

Instead of coding all of this by hand, I recommend to use Slick carousel instead: http://kenwheeler.github.io/slick/
This will also give you a better user-experience, as Slick supports nice transitions between the slides.

Thanks. I tried that because they looked really nice but I had a problem with the {{#each)) part because of the “active” class. All the slides appear together from mongo and, if you remove the class, none of them appear :confounded: Must be a workaround but actually, @robfallows gave me just what I needed and it works really nicely now.