flimflam57
flimflam57

Reputation: 1334

Generate dynamic events template in Meteor

Let's say I have a template in Meteor that is generating multiple card panels using Materialize. The key idea is that it's generating unique values inside each panel.

<template name="Teacher_Information">
{{#each TeacherNames}}
<div class="row">
 <div class="col s12">
  <div class="card blue-grey darken-1">
    <div class="card-content white-text">
      <a href="#" id="img-{{@index}}"><img src={{formatImage FullName}} alt="" class="circle"></a>
      <span class="card-title">{{formatName FullName}}</span>
      <span>Some text here.</span>
      <span>
        <form>
          <input name="dayGroup" type="radio" id="teach-sunday-{{@index}}" value="Sunday">
          <label for="teach-sunday-{{@index}}" class="white-text">SU</label>
          <input name="dayGroup" type="radio" id="teach-monday-{{@index}}" value="Monday">
          <label for="teach-monday-{{@index}}" class="white-text">MO</label>
          <input name="dayGroup" type="radio" id="teach-tuesday-{{@index}}" value="Tuesday">
          <label for="teach-tuesday-{{@index}}" class="white-text">TU</label>
          <input name="dayGroup" type="radio" id="teach-wednesday-{{@index}}" value="Wednesday">
          <label for="teach-wednesday-{{@index}}" class="white-text">WE</label>
          <input name="dayGroup" type="radio" id="teach-thursday-{{@index}}" value="Thursday">
          <label for="teach-thursday-{{@index}}" class="white-text">TH</label>
          <input name="dayGroup" type="radio" id="teach-friday-{{@index}}" value="Friday">
          <label for="teach-friday-{{@index}}" class="white-text">FR</label>
        </form>
      </span>
    </div>
    <div class="card-action white-text">
      <form class="input-field col s6 card-selector">
        <select multiple id="teacher-students-day1-{{@index}}">
          <option value="" disabled selected>Select Students</option>
          {{#each StudentList1}}
            <option value= '{{FullName}}'>{{formatName FullName}} ({{Level}})</option>
          {{/each}}
        </select>
      </form>
      <form class="input-field col s2 card-selector">
        <select multiple id="days-off-{{@index}}">
          <option value="" disabled selected>Off</option>
          <option value="Sunday">Su</option>
          <option value="Monday">Mo</option>
          <option value="Tuesday">Tu</option>
          <option value="Wednesday">We</option>
          <option value="Thursday">Th</option>
          <option value="Friday">Fr</option>
          <option value="Saturday">Sa</option>
        </select>
      </form>
    </div>
  </div>
  </div>
 </div>
{{/each}}
</template>

Depending on the length of 'TeacherNames' it will create that many panels. It uses the @index syntax to produce unique names.

Now when I need to create the events template, what I'd need would be something like:

Template.Teacher_Information.events({
  'click #img-0': function() {
    // do some stuff

  },
  'click #image-1': function() {
    // some more stuff

  },
  ...
  ...
});

I can't insert a for loop inside the template to generate the key:value pairs, so I'm pretty much at a standstill on how I could generate a dynamic events template like that.

Upvotes: 0

Views: 57

Answers (1)

Michel Floyd
Michel Floyd

Reputation: 20226

The normal pattern for doing this is to simply define a template at the lower level and then attach events to that. In your case:

<template name="Teacher_Information">
{{#each TeacherNames}}
  {{> oneTeacher}}
{{/each}}
</template>

Then your oneTeacher template would be everything you had inside the {{#each TeacherNames}} loop before.

Now you can attach events to the oneTeacher template and get the data context of the teacher in your event:

Template.oneTeacher.events({
  'click a'(ev){
    console.log(this); // 'this' will be a teacher object
  }
});

Understanding this was one of the early "OMG this is so much simpler!" moments when I was learning Meteor.

While you're at it you can also DRY up your days of week template by looping over an array you build in code:

Template.oneTeacher.helpers({
  dow() { return [
    { number: 1, day: "Sunday", abbr: "SU" },
    { number: 2, day: "Monday", abbr: "MO" },
    { number: 3, day: "Tuesday", abbr: "TU" },
    { number: 4, day: "Wednesday", abbr: "WE" },
    { number: 5, day: "Thursday", abbr: "TH" },
    { number: 6, day: "Friday", abbr: "FR" },
    { number: 7, day: "Saturday", abbr: "SA" }
   ];
  }
});

Then you can do:

<form>
{{#each dow}}
  <input name="dayGroup" type="radio" value={{name}}>
  <label class="white-text">{{abbr}}</label>
{{/each}}
</form>

You'll find that you won't really need to give every DOM object unique IDs when you are handling events at the lowest levels.

Upvotes: 1

Related Questions