Meteor - Pass variable in templates arguments - meteor

I am trying to do something like this:
<template name=week>
{{#each days}} //from an array in helpers with values [0,1,2,3,4,5,6]
{{> day dayOfWeek="<How can I have the value here?>"}}
{{/each}}
<template name>
Question1: How to retrieve the current value of the array to pass it to the template included?
<template name=day>
{{#autoForm collection=users doc=user ...}}
{{#each days}} //from an array in helpers with values [0,1,2,3,4,5,6]
{{>afFieldInput name='profile.availability.<dayOfWeek>.from'}}
{{/each}}
{{/autoForm}}
<template name>
Question 2: How can I dynamically substitute dayOfWeek inside the name?

Try this :
Question 1 :
<template name="week">
{{#each days}} //from an array in helpers with values [0,1,2,3,4,5,6]
{{> day dayOfWeek=this}}
{{/each}}
<template name>
Question 2 :
HTML
<template name="day">
{{#autoForm collection=users doc=user ...}}
{{#each day in days}} //from an array in helpers with values [0,1,2,3,4,5,6]
{{> afFieldInput name=name}}
{{/each}}
{{/autoForm}}
<template name>
ES2015
Template.day.helpers({
name(){
const dayOfWeek = this.dayOfWeek;
return `profile.availability.${dayOfWeek}.from`;
}
});
Note : this is using latest Blaze constructs and ES2015 from Meteor 1.2

Related

Treat error when when key does not exist

How can one make spacebars react when the set key does not exist in the template?
Example:
//JavaScript
Template.foo.helpers({
//"zaz" : "hello",
"bar" : 1
});
...
<!-- Template -->
<template name="foo">
{{bar}}
{{#ifExist zaz}}
{{zaz}}
{{else}}
"fill-me"
{{/ifExist}}
</template>
You can just check if your helper is defined by using a simple if statement followed by the helper or value you want to check:
<template name="foo">
{{bar}}
{{#if zaz}}
{{zaz}}
{{else}}
fill-me
{{/if}}
</template>

How does parent template pass data to child template?

So I have serverl base templates:
<template name="Base1">
<div>basetitle1</div>
</template>
<template name="Base2">
<div>basetitle2</div>
</template>
and the base templates is included in different templates.
<template name="Parent1">
{{> Base1}} # basetitle1 => Parent1.Title1
{{> Base2}} # basetitle2 => Parent1.Title2
</template>
<template name="Parent2">
{{> Base1}} # basetitle1 => Parent2.Title1
{{> Base2}} # basetitle2 => Parent2.Title2
</template>
basetitle1 and basetitle2 are different when in different parent templates.
So how can I pass data from parent template to child template?
You can pass data to the children template via Object creation using keyword arguments.
Try this:
<template name="Parent">
{{> Base1 basetitle1=Title1}} # Get Title1 from a helper or data
{{> Base2 basetitle2="Parent.Title2"}} # Pass a string
</template>
<template name="Base1">
<div>{{basetitle1}}</div>
</template>
<template name="Base2">
<div>{{basetitle2}}</div>
</template>

Fastest way to check whether the cursor returned by a template helper is empty?

I often do something like this, using the items helper twice:
{{#if items}}
<h1>Items</h1>
{{#each items}}
{{> item}}
{{/each}}
{{/if}}
Template.foo.helpers
items: ->
Items.find
bar: true
,
sort: created: -1
transform: (item) ->
i.good = true
i
Is Meteor doing extra work in this scenario? Would it be more efficient to switch the if to use something like areItems?
areItems: ->
Items.find
bar: true
.count() > 0
You can use {{else}}
{{#each this}}
{{> item}}
{{else}}
<h1>No Items</h1>
{{/each}}
In the template, you can use {{#with items}} and then either 'this.count' or 'this.length' to check whether your helper returned any items.
Use this.count if 'items' is a cursor, e.g. the result of a find() operation:
{{#with items}}
{{#if this.count}}
<h1>Items</h1>
{{#each this}}
{{> item}}
{{/each}}
{{/if}}
{{/with}}
Use this.length if 'items' is an array:
{{#with items}}
{{#if this.length}}
<h1>Items</h1>
{{#each this}}
{{> item}}
{{/each}}
{{/if}}
{{/with}}
Use #with, #if this.length, and .fetch:
{{#with items}}
{{#if this.length}}
<h1>Items</h1>
{{#each this}}
{{> item}}
{{/each}}
{{/if}}
{{/with}}
Template.foo.helpers
items: ->
Items.find
bar: true
,
sort: created: -1
transform: (item) ->
i.good = true
i
.fetch()
You can do what you want using spacebars' #with block tag.
Like this:
{{#with items}}
{{#if this.count}}<h1>Items</h1>{{/if}}
{{#each this}}
{{> item}}
{{/each}}
{{/with}}
The block tag is documented here. The relevant quote is:
If the argument to #with is falsy (by the same rules as for #if), the content is not rendered.
update: fixed code for desired behaviour. Also while my example demonstrates making one helper call it is better practice to make an 'itemList' template and include it by using {{> itemList items}}.
I found that simply {{#if items.count}} was sufficient.
{{#if items.count}}
<h2>Below there are items</h2>
{{/if}}
{{#each items}}
<div class="item-name">{{this.name}}</div>
{{else}}
<h2>There are no items</h2>
{{else}}

Polymorphism in Meteor Templates

Say I have a Meteor application which displays widgets. A widget can have one of several forms:
<template name="textWidget">
<h1>{{myTitle}}</h1>
<p>{{myTextContent}}</p>
</template>
<template name="imgWidget">
<h1>{{myTitle}}</h1>
<img src="{{myImagePath}}" />
</template>
<template name="listWidget">
<h1>{{myTitle}}</h1>
<ul>
{{#each items}}
{{> listWidgetItem}}
{{/each}}
</ul>
</template>
Is there a good pattern for rendering a specific template given a record type?
Naively, I can do something like:
<template name="masterTemplate">
{{#each widgets}}
{{#if widgetType "text"}}
{{> textWidget}}
{{else}}
{{#if widgetType "img"}}
{{> imgWidget}}
{{else}}
{{if ... }} ... {{/if}}
{{/if}}
{{#/if}}
{{/each}}
</template>
With a helper like:
Template.masterTemplate.widgetType = function(cmp) {
return cmp === this.data.type;
};
This seems like a very clunky and unflexible way to operate though. Am I missing an obvious library or design pattern for this use case?
You can try something like this:
UI.registerHelper('widget', function () {
var templateName = this.data.type + 'Widget';
return Template[templateName].extend({ data: this });
});
and you can use it as follows:
{{> widget context}}
or
{{#with context}}
{{> widget}}
{{/with}}

How do I pass dynamic variables into templates in Meteor?

Using data of the form:
users =
_id: 'foo'
books: [
{name: 'book1'}
{name: 'book2'}
]
<template name="user">
{{#each get_users}}
{{> shelf}}
{{/each}}
</template>
<template name="shelf">
{{#each books}}
{{> book}}
{{/each}}
</template>
<template name="book">
<div contenteditable="true" data-id="{{_id}}">{{name}}</div>
</template>
I want _id in the book template to refer to the _id of the user, but _id is not in scope inside the book template. I'd like to be able to do something like {{> book _id}}, but that doesn't work, I think because book can only have one argument, and that is each {name: 'book1'} doc.
Use a custom block helper. It would be nicer if Meteor allowed multiple arguments for custom block helpers (this is supported in Handlebars). Since it doesn't (see the the wiki), this is the best I came up with, passing a modified this to the subtemplate book.
<template name="shelf">
{{#my_iterator}}
{{> book}}
{{/each}}
</template>
Templates.shelf.my_iterator = (options) ->
html = "
for book in this.books
this.name = book.name
html += options.fn this
html

Resources