Mark
Mark

Reputation: 13

Using dynamic templates in meteor

I'm really stuck trying to use dynamic templates in meteor, and applying filters to the data which populates them. I'd be really grateful for some help.

To give a simple example, I'd like to be able to input tasks into a to do list, with a tag, for whether it is a big or a little task. Then I'd like to be able to display a table of big tasks, and a table of little tasks, separately.

Here are some code extracts, adapted from the official meteor blaze tutorial, so you can see in a general sense what I'm trying to do.

body.html extract

<body>
  <div class="container">
    <header>
      <h1>Todo List</h1>

        <form class="new-task">
          <input type="text" name="text" placeholder="Type to add new tasks" />
          <input type="text" name="taskType" placeholder="Big/little" />
          <button type = "submit">submit</button>
        </form>
    </header>
    <h1>big tasks</h1>
    <ul>
      {{> Template.dynamic template="task" data=bigTasks}}
    </ul>
    <h1>little tasks</h1>
    <ul>
      {{> Template.dynamic template="task" data=littleTasks}}
    </ul>
  </div>
</body>

task.html extract

 <template name="task">
  <li class="{{#if checked}}checked{{/if}}">
    <button class="delete">&times;</button>

    <input type="checkbox" checked="{{checked}}" class="toggle-checked" />

    <span class="text">{{text}}</span>
  </li>
</template>

task.js extract

Template.task.helpers({
  bigTasks() {
    return Tasks.find({}, { taskType: Big, sort: { createdAt: -1 } });
  },
});

Template.task.helpers({
  littleTasks() {
    return Tasks.find({}, { taskType: Little, sort: { createdAt: -1 } });
  },
});

I realise this is perhaps a little more a request for a tutorial, than a specific question, but would be grateful for anything which you can offer

Upvotes: 0

Views: 96

Answers (2)

Mark
Mark

Reputation: 13

For anyone encountering the same challenges, Styx's answer above works, but I found that I needed to also make a few changes to the syntax of the helper function:

Template.body.helpers({
  bigTasks() {
    // Show newest tasks at the top
    const tasks = Tasks.find({taskType: "Big"}, {sort: { createdAt: -1 } }).fetch();
  return { tasks };
  },
  littleTasks() {
    // Show newest tasks at the top
    const tasks = Tasks.find({taskType: "Little"}, {sort: { createdAt: -1 } }).fetch();
  return { tasks };
  },
});

Styx - thanks so much. I really appreciate you taking the time to help this newbie find my way. All the best!

Upvotes: 0

Styx
Styx

Reputation: 10076

There are numerous issues with your code.

First, you're using Template.dynamic wrong way. It's supposed to include template which name is dynamic.

Second, using Template.dynamic you're using data=<helper name>. That's correct form, but you're using it in Template.body, so these helpers also should be in Template.body, not in Template.task.

And, third issue is that you forgot to wrap your task template content in {{#each}}...{{/each}}.

As your question is about using Template.dynamic, here is how it should be (though there is an another, better way to implement this):

Template.body.helpers({
  bigTasks() {
    const tasks = Tasks.find({}, { taskType: Big, sort: { createdAt: -1 } }).fetch();
    return { tasks };
  },
  littleTasks() {
    const tasks = Tasks.find({}, { taskType: Little, sort: { createdAt: -1 } }).fetch();
    return { tasks };
  },
});

task.html:

<template name="task">
  {{#each tasks}}
    <li class="{{#if checked}}checked{{/if}}">
      <button class="delete">&times;</button>
      <input type="checkbox" checked="{{checked}}" class="toggle-checked" />
      <span class="text">{{text}}</span>
    </li>
  {{/each}}
</template>

Upvotes: 0

Related Questions