Search code examples
javascriptmeteormeteor-blazejquery-isotope

Meteor - Isotope doesn’t work with nested templates


I’m trying to integrate Isotope with my Meteor App, but I’ve been having some complications. When I use directly html inside my Isotope container it works fine, but when I try using nested templates, Isotope doesn’t work. Here is what I have at the moment.

Home.html

<template name="home">
  <div class="grid">
    {{> card }}
  </div>
</template>

Home.js

import './home.html';

Template.home.onRendered ( function() {

      $('.grid').isotope({
        // options
        itemSelector: '.grid-item',
        layoutMode: 'masonry',
        masonry: {
          gutter: 24
        }
      });
 });

Card.html

<template name="card">

  {{#each publications}}
    <div class="grid-item">
      <div class="card-margin">
        <img src="{{avatar}}" alt="" class="avatar"/>
        <div class="name"> {{username}} <div class="dropdown"><a>></a><div class="dropdown-content">{{#if isOwner}}<button class="delete">&times;</button> <button class="edit">Edit</button>{{else}}<button>Report</button> <button>Unfollow</button>{{/if}}</div></div></div>
        <div class="date" id="date-show">{{customDate}} </div>
        <p class="card">
            {{ pub }}
        </p>
      </div>
    </div>
  {{/each}}
</template>

Any help would be great.


Solution

  • The problem itself is that your home template is rendered before its nested templates. Thus, there are no any .grid-item elements.

    The only way to solve that in your situation is to postpone initializing .isotope(...) using Meteor.defer() or Meteor.setTimeout() in hopes that that would give nested templates enough time to render:

    Template.home.onRendered(function() {
      Meteor.setTimeout(function() {
        $('.grid').isotope({
          // options
        });
      }, 250);
    

    Added:

    Another option would be for nested templates to notify its parent from their onRendered functions:

    Main template:

    Template.home.onCreated(function() {
      this.renderGrid = _.debounce(() => {
        $('.grid').isotope({
          // options
        });
      }, 250);
    });
    
    Template.home.events({
      'ready.griditem .grid'(e, tpl) {
        tpl.renderGrid();
      }
    });
    

    Nested template:

    Template.card.onRendered(function() {
      $('.grid').trigger('ready.griditem');
    });