handlebarsjs how to imbricated many loop/each - handlebars.js

http://jsfiddle.net/0ttb7pug/1/
I do not have the desired result, only first loop executed
{{#each loop1}}
<ul>{{val1}}
{{#each loop2}}
<li>{{val2}}</li>
{{/each}}
</ul>
{{/each}}

Since your second {{#each}} is within the first, its context has changed to that of each object in the first array. To resolve your issue, you need to get access to the root context of your template data (or at least the context above), which can be achieved with either ../loop2 (which takes you up one context) or #root.loop2 (which takes you to the top-most context)
{{#each loop1}}
<ul>{{val1}}
{{#each ../loop2}} //or #root.loop2
<li>{{val2}}</li>
{{/each}}
</ul>
{{/each}}

Related

Adding a css class in a dynamically created handlebars template

I have a JSON object that I am looping through to dynamically create x amount of ULs then LIs. I need to create two {{#each}} to create the content. However when I add a CSS class to my handlebars template it does not come through onto the UL as it does in the second {{#each}} - how do I stop this? Here is the template:
<div class="{{panel-container__Css-class}} {{panel-menu__Css-class}}" data-component="panel">
{{#each sections}}
<ul id="{{id}}" class="{{panel-menu__Css-class}}">
{{#each list}}
<li>{{title}}</li>
{{/each}}
</ul>
{{/each}}
</div>
Here is what i am passing in:
<nav data-component="navigation">
{{> nav-dropdown menu-button__Css-class="menu-button" menu-button__Css-class-nav="panel" target-id="panel-nav" }}
{{> nav-dropdown menu-button__Css-class="region-button" menu-button__Css-class-nav="region" target-id="panel-region" menu-button__copy=panel.copy}}
{{!--var links = [{"title": "Test","url": "/"}];--}}
{{> panel panel-menu__Css-class="navigation__menu-styles" panel-container__Css-class="navigation__menu-container" sections=navigation.sections links=navigation.sections.list }}
</nav>
I think what you are looking for is the Handlebars path that will allow you to obtain the value of panel-menu__Css-class from within {{#each sections}}. You need to understand that when you are within {{#each sections}}, your this context is the currently iterated element of the sections array. You must step up a level to the parent context which has the panel-menu__Css-class property you are trying to access:
<ul id="{{id}}" class="{{../panel-menu__Css-class}}">

Meteor Blaze display array

I have collections like this:
I want to iterate over object.questions.teema for example.
I have helper:
Template.game.helpers({
theGame: function() {
var theGame = Game.findOne({_id:"LhQmaZKW8eJNenyX9"})
console.log(theGame)
return theGame
}
});
and template:
<template name="game">
{{#with theGame}}
{{#each theGame.questions}}
{{teema}}
{{/each}}
{{/with}}
</template>
But it doesnt work, what is wrong with the template?
'#each theGame.questions' Will not work inside the #with, because you can access the 'theGame' object directly.
The point is when you try to get theGame object inside the #with it will return you undefined, because 'theGame' object does not have theGame property, Which you want to access inside #with block.
<template name="game">
{{#with theGame}}
{{#each questions}}
//Thie #each because you have nested array. As I can see in your console log.
{{#each this}}
{{teema}}
{{/each}}
{{/each}}
{{/with}}
</template>
What is {{teema}} supposed to be?
Regardless, as you can see from your console.log statement, {{theGame.questions}} returns another array. But that array returns objects. This is really hard to query for with Blaze.
The better solution would be to flatten it out so that your data is shaped like this:
questions: [
{
a: 'asdfkjah',
level: 'askdjfhal',
q: 'asdkfh',
teema: 'asdkfjh'
vaartus: 100
},
{
...
}
]
This way you don't have an array nested in an array. That will allow you to:
{{#with theGame}}
{{#each theGame.questions}}
{{this.teema}}
{{/each}}
{{/with}}
theGame.questions is an array (that you iterate over) of array of objects which have the teema key. So you still need to iterate over the 2nd level array, or define a specific item in that array before you can eventually reach the object with teema property.
Maybe something like:
{{#with theGame}}
{{#each questions}}
{{#each this}}
{{this.teema}}
{{/each}}
{{/each}}
{{/with}}
But it depends on why you have these 2-level arrays in the first place.

Passing through variable into partial and using an #is helper - Handlebars

I'm trying to pass a variable (tag name) into a Handlebars partial and use an #is block helper on the tag but for some reason it just won't play ball. This is my code:
Call to my partial and passing through the tag name.
{{> nav tagged='page' }}
In the partial itself I do the following (tagged is the variable name passed through):
{{#each tags}}
{{#is tag tagged}}
{{#each pages}}
// Do code here
{{/each}}
{{/is}}
{{/each}}
If I just render the tagged variable it displays the variable value as expected so a bit confused as to why its not working.
Thanks.
The issue you have is that the tagged variable is in the parent context but you're trying to reference it within the #each tags loop.
You can reference the parent context with ../ so the working code would be
{{#each tags}}
{{#is tag ../tagged}}
{{#each pages}}
// Do code here
{{/each}}
{{/is}}
{{/each}}

How to get index for parent loop in Handlebars template?

<script id="contact-row" type="text/x-handlebars-template" >
{{#each rows}}
<tr>
{{getInputField #index "country" country }}
{{#each contactData}}
{{getInputFieldForData #index "contractName" contractName }}
{{/each}}
</tr>
{{/each}}
I want to get the index of the parent in the inner #each loop. I tried ../#index but that gives error.
Looks like things have changed...
To get the index of a parent {{#each}} block from within a child {{#each}} block use the {{#../index}} syntax.
{{#each foo}}
{{#index}} // Parent Index Reference
{{someProperty}} // Parent property
{{#each baz}}
{{#index}} // Child Index Reference
{{#../index}} // Parent Index Reference <--
{{someProperty}} // Child property
{{/each}}
{{/each}}
The link in the accepted answer has this solution, just posting the details here for posterity's sake.
It looks like this is not currently possible the way you want to do it: https://github.com/wycats/handlebars.js/issues/491
But you could set the index to a new variable in the outer scope to access it.

How to access outer {{#each}} collection value in the nested loop

What is the standard way to access outer #each collection values in the loop?
for example:
<template name="example">
{{#each outerCollection}}
<tr>
{{#each innerCollection}}
<td>{{aaa}}</td>
{{/each}}
</tr>
{{/each}}
</template>
Template.example.aaa = function(){
// cannot access outerCollection values
}
in above Template.example.aaa, this points to the inner collection.
I cannot find way to access outerCollection items.
My solution is like below, I am defining my own helper function.
Is it a standard Meteor way to achieve this purpose?
<template name="example">
{{#each outerCollection}}
<tr>
{{#each innerCollection}}
<td>{{myHelper ../outerItem innerItem}}</td>
{{/each}}
</tr>
{{/each}}
</template>
Handlebars.registerHelper('myHelper', function (outItem, inItem) {
// can access outerCollection via outerItem
});
I found a similar question for the case of inner event handler access.
I think you've answered this yourself! Using ../ is documented in https://github.com/meteor/meteor/wiki/Handlebars.
You can use below code to fetch outer collections.
suppose you have collection called as Collection.Customer and Collection.RechargePlan and you are using both in a template for updating Customer.
Customer = {"name":"James", "rechargeplan":"monthly"};
RechargePlan = [{"rechargeplan": "monthly"},{"rechargeplan": "yearly"}];
//Inside template, Bydefault Customer is available.
{{#each RechargePlan}}
{{#if equals ../rechargeplan rechargeplan}}
//Hurray Plan matches
{{/if}}
{{/each}}
In above code, ../rechargeplan is actually Customer.rechargeplan, ../ actually went one step above heirarchy and then accessed the field if available, since Customer is already available to template, it's field is picked up.

Resources