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}}
Related
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;
});
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/
How can I add a dynamic class name in an #each block to my Handlebars template, where the class name isn't part of the block scope?
<div class="{{className}}>...</div>
{{#each items}}
<div class="{{className}}">
...
</div>
{{/each}}
The first <div> will see the class name, whereas the second one in the #each block doesn't, because it is now looking for a className in items.
Is it possible to see outside of the items scope in the #each block?
You need to go back one scope (or possibly more), using ../ to access a global variable. In your case if your pass i className as one attribute and ìtems`as another, your code should look like this:
{{#each items}}
<div class="{{../className}}">
...
</div>
{{/each}}
#root.classname will help on any depth of scope.
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.
I do not know if this is specific to the requirejs handlebar plugin but when I have a template like :
<h1>abc</h1>
{{#if testcondition1}}
<h1>def</h1>
{{/if}}
{{#if testcondition2}}
<h1>ghi</h1>
{{/if}}
<h1>xyz</h1>
I get a empty line if one condition is false.
so like:
<h1>abc</h1>
<h1>ghi</h1>
<h1>xyz</h1>
and not
<h1>abc</h1>
<h1>ghi</h1>
<h1>xyz</h1>
Is this the expected behavior?
I'd like to get no lines without recurring to string manipulation after the template compilation. I know that lines get ignored in html but this can be really annoying especially in loops.
If you look at the newline placements in your code:
<h1>abc</h1>\n
{{#if testcondition1}}\n
<h1>def</h1>\n
{{/if}}\n
{{#if testcondition2}}\n
<h1>ghi</h1>\n
{{/if}}\n
<h1>xyz</h1>\n
You can see that if the first condition is false, the code without the skipped branch is:
<h1>abc</h1>\n
\n
{{#if testcondition2}}\n
<h1>ghi</h1>\n
{{/if}}\n
<h1>xyz</h1>\n
which gives you two newlines in a row.