Display surrounding HTML only if Handlebar variable is given - javascript

Is it possible to only display surrounding HTML around a Handlebar (or Mustache) variable if it is not empty (or not null, etc)? For instance, given the following context and template:
var data = {field1:123,field2:123,field3:'',field4:123};
<dl>
<dt>field1:</dt><dd>{{field1}}</dd>
<dt>field2:</dt><dd>{{field2}}</dd>
<dt>field3:</dt><dd>{{field3}}</dd>
<dt>field4:</dt><dd>{{field4}}</dd>
</dl>
The following would be displayed:
field1:123
field2:123
field4:123

Rather writing if block for each field you can use the each block helper
<dl>
{{#each this}}
{{#if this}}
<dt>{{#key}}</dt><dd>{{this}}</dd>
{{/if}}
{{/each}}
</dl>
Here you are traversing through the object and checking if the current field is set then display the key and value otherwise move to the next field. It can help you if you have a large set of data then you don't need to write the if block again and again.Hope this helps.
Working example can be found here : http://jsfiddle.net/prabhat_rai/rveap9jb/

The simplest way would be to use the if statement:
<dl>
{{#if field1}}
<dt>field1:</dt><dd>{{field1}}</dd>
{{/if}}
{{#if field2}}
<dt>field2:</dt><dd>{{field2}}</dd>
{{/if}}
...
</dl>

Related

How to check if {{#index}} is even or odd in Handlebars?

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}}

Handlebars expression outside of #each helper

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.

Emberjs - Accessing a parent inside {{#each}} loop

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.

If statement within another if statement in Handlebars templates

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!

Meteor: Re-use template with different data

I've got a few templates which list items (log lines, users) and style them accordingly in tables. Now I've added a "search" page which searches for a string in different item types and displays them on one page. In terms of layout, I want to reuse the original templates, but obviously with the data returned by the search.
How can I do that without duplicating the template itself in the HTML file?
Put another way: How can I use the actual data from the top-level template in the sub-templates.
Small example:
<template name="user_list">
{{#each user_list}}
</template>
<template name="users">
{{> user_list}}
</template>
<template name="search">
{{> user_list}}
{{> group_list}}
</template>
In .coffee:
Template.users.user_list = ->
[a,b,c,d]
Template.search.user_list = ->
[b,c]
Maybe this is an easy one, which would show how little I really understood about Meteor.
Just put the template you want to use inside the {{#each}} statement. Then each item in the array will be the context for that inner template.
HTML file
<template name="users">
<ul>
{{#each UserArr}}
{{> userItem}}
{{/each}}
</ul>
</template>
<template name="userItem">
<li>{{username}} {{profile.name}}</li>
</template>
JS file
Template.users.UserArr = function()
{
return Meteor.users.find({});
};
another solution is to put your request in a Session attribute and check for its existence when querying for the users. By default Session.get("userQuery") would return undefined but once you enter something in the search field you change that with Session.set("userQuery", {type: "something"})
Now in the coffeescript you could say:
Template.users.user_list = ->
if(Session.get("userQuery"))
[a,b,c,d]
else
[b,c]
or alternatively use a MiniMongo query because it is much nicer :-)
the nice thing is that your HTML will rerender because it is reactive to the Session's content.

Categories