Context
I’m trying to use Handlebars to loop through events and then nested loop through images. I need to select only the images that correspond to the event that the event loop is currently on.
Problem
I can’t pass the _id of the event inside the image nested. Is there a work-around for this? I realize I can pass variables through a helper but it would be good to know if there is a simpler way.
The following is meta-code for what is not working so far:
//attach venue image to each venue
{{#each myVenues}}
{{#each myImages}}
{{#if myVenues._id == myImages._id}}
<img src="{{this.url}}>
{{/if}}
{{/each}}
{{/each}}
Any help would be appreciated!
More recent versions of spacebars supports referencing the parent. Try:
{{#each myVenues}}
{{#each myImages}}
{{#if ../_id == myImages._id}}
<img src="{{this.url}}>
{{/if}}
{{/each}}
{{/each}}
EDIT:
Christian Fritz pointed out that your conditional logic in the if statement won't work with spacebars. If you set up a helper to evaluate the conditional logic, you can still get this working:
{{#each myVenues}}
{{#each myImages}}
{{ifequals ../_id myImages._id}}
<img src="{{this.url}}>
{{/if}}
{{/each}}
{{/each}}
Then in a helper:
Template.registerHelper('ifequals', function(a,b) {
return a === b;
});
Related
I'm iterating through an array, but I want to change the div color according to whether the index is odd or even.
Handlebars is not recognizing {{#index}} within an if statement, such as this:
{{#each org as |building i|}}
{{#if (isEven {{#index}})}}
...
{{/if}}
{{/each}}
the isEven is a helper I created to check. It works well, but I can't seem to pass the index to it.
Please keep in mind that I'm using Express Handlebars.
Try it without the brackets around #index
{{#if (isEven #index)}}
...
{{/if}}
I would like to use to refer to another template within an {{#each}} loop
html:
{{#each listOfItems}}
{{>{{variableOne}}}}
{{/each}}
which should render
<Template name="one">
One
</Template>
or
<Template name="two">
Two
</Template>
depending on the js
other tried syntax include
{{>'{{variableOne}}'}}
or
{{>Template.dynamic template={{variableOne}}}}
Any help or workaround greatly appreciated!
Not sure what are you trying to accomplish. I'm assuming you are using Blaze rendering engine. If you want to pass parameters try this:
{{#each}}
{{> TemplateName variable=variable}}
{{/each}}
Or if you want to show certain template depending on variable value try this (watch out - eq is meant as global helper for comparing values):
{{#each}}
{{#if variable eq 1}}
{{> TemplateOne}}
{{else}}
{{> TemplateTwo}}
{{/if}}
{{/each}}
Assuming that the list you iterate over contains the template names, this will get you what you want:
html:
<template name="hello">
{{#each template in myTemplates}}
{{> Template.dynamic template=template }}
{{/each}}
</template>
<template name='foo'>foo-template</template>
<template name='bar'>bar-template</template>
js:
Template.hello.helpers({
myTemplates() {
return ['foo', 'bar'];
},
});
Okay so here is the the template I'm using
<script id='goalNavTemplate' type="text/x-handlebars-template">
{{#each this}}
<div class="bubble" data-dismiss="modal" data-Name="{{name}}"
style="background:{{color}} url(images/{{icon}}IconSmall.png)
no-repeat 13px 14px;"></div>
{{/each}}
</script>
And then I'm adding my objects in the array to the DOM with handlebars.
var template = Handlebars.compile($('#goalNavTemplate').html());
$('#selectGoalModal .modal-body').append(template(goals));
This works how I like, yet what I would like to do next is be able to update the DOM when a new object is added to the array (through user input). Yet if I call:
$('#selectGoalModal .modal-body').append(template(goals));
again it will add all the objects to the DOM and not just the last one. My current workaround is to remove the previously added elements and then use the above line of code after the array is updated. I was wondering if there is a more efficient way of doing this using handlebars? Like is there some way to bypass #each and just append the last object in the array? Would you use a helper? If so, how? Any insight into this would be awesome.
You can add some flags to goals item, e.g. datatime and check it by HB:
{{#each this.items}}
{{#ifCond this.dt '>=' ../options.dt }}
<div class="bubble" id="bub-{{id}}" style="background-color:{{color}};">
{{id}} - {{name}}
</div>
{{/ifCond}}
{{#updateDOM "#bub-" id dt}}{{/updateDOM}}
{{/each}}
http://jsfiddle.net/2jvndb0L/5/
I've searched and searched and I cannot find the solution to the following question:
How do you access a parent inside an each loop?
So here's the scenario, I need to pass an id of the parent with the action helper within a nested each loop.
{{#each}} {{! iterating the model here (arrayController) }}
{{#if showingApplicants}} {{! this is set by a button that changes a property inside this particular model object}}
{{#each applicants}}
<button {{action addLabel _id}}>Add Label...</button>
{{/each}}
{{/if}}
{{/each}}
I have tried doing ../_id and ../../_id. Both of which represent an undefined value. Any clues? ALSO: Is it possible to pass two values in the action helper?
You can create variables on your #each blocks so you can refer to them on any context
{{#each x in content}}
{{#if x.showingApplicants}}
{{#each applicant in x.applicants}}
<button {{action addLabel x.id}}>Add Label...</button>
{{this.controllerProperty}}
{{x.parentModelProperty}}
{{y.childModelProperty}}
{{/each}}
{{/if}}
{{/each}}
You could also not name applicant, but if you start by naming the outer context, I would suggest doing it for the nested each as well for consistency and to avoid possible name clashes (between the outer variable and child properties).
Hope this helps
The workaround for this issue was to map out the model data to have an id object that contained the parent id and the child id.
These are all objects which I am passing to the handlebars template.
self.template = template({ data: self.model, lang:self.lang, page:self.mainPage, subpage:self.param });
Then inside foreach loop I have an if statement where I am not able to access the parent context element. The code which i have inside the template and the problem is shown bellow:
{{#each data}}
<h1>{{../subpage}}</h1> --> This is giving me a subpage value
{{#if this.brand}}
{{#if ../subpage}}
<h1>WHY IS THIS NOT SHOWING?</h1> --> This is what i am trying to achieve
{{/if}}
{{/if}}
{{/each}}
Any ideas how to achieve this? Thank you very much for all answers/comments!
{{#if this.brand}} goes down into context another level, so you must escape to the parent context not once, but twice.
Your template should thus be:
{{#each data}}
<h1>{{../subpage}}</h1>
{{#if this.brand}}
{{#if ../../subpage}}
<h1>This shows now!</h1>
{{/if}}
{{/if}}
{{/each}}
This should work with a self.model value similar to:
[
{
brand: "Brand A",
otherFields: "here"
}
]
Here is a jsFiddle that demonstrates the solution: nested if statement context escaping
I hope that helps!