I am new to JsViews. In one of the template, I have to set multiple conditions for rendering :
<tr>
{{if condition1 || condition2 || condition3}}
<td class="formLabel"
style="padding-left:2px;vertical-align:middle;text-align:left;font-size:8pt;font-family:sans-serif;"
width=""><span id="{{attr:firstChild().id()}}_labelSpan" style="color:#000000;">{{attr:childAtIndex_(1).paramAt_('label')}}</span>
</td>
<td style="vertical-align:middle;" width="200px">{{:renderChildren()}}</td>
{{else}}
<td style="vertical-align:middle;" width="200px">{{:renderChildren()}}</td>
<td class="formLabel"
style="padding-left:2px;vertical-align:middle;text-align:left;font-size:8pt;font-family:sans-serif;"
width=""><span id="{{attr:firstChild().id()}}_labelSpan" style="color:#000000;">{{attr:childAtIndex_(1).paramAt_('label')}}</span>
</td>
{{/if}}
</tr>`
Can I put the multiple condition in the a method at the template level
Yes, you can do that. See the documentation on "Paths and expressions".
As examples, see the sample at the bottom of the {{if}} tag topic, which does:
{{if members && members.length}}
...
{{else standby && standby.length}}
Standby only:
...
{{else}}
No members!
{{/if}}
This sample also shows examples of using expressions in JsRender tags, such as:
{{if address && address.street}}
and
{{:~lateMessages.noAddress || ~messages.noAddress}}
Related
I am trying to iterate using the properties of an object to dynamically print a table having an array with the properties and an object with the values of each property.
I don't know how to do the 2 iterations using hbs express from handlebars
people: [{
name: "ken",
lastname: "grace",
age: 10
},
{
name: "ron",
lastname: "bond",
age: 20
}];
properties = ["name","lastname", "age"];
HTML CODE:
<table>
<thead>
<tr>
{{#each properties as |property index|}}
<th>
<span>{{property}}</span>
</th>
{{/each}}
</tr>
</thead>
<tbody>
{{#each people}}
<tr>
{{#each properties}}
<th>
{{!-- trying something like: --}}
{{!-- {{people.property}} --}}
</th>
{{/each}}
</tr>
{{/each}}
</tbody>
</table>
As user #76484 mentioned, you want to use the built-in lookup helper:
The lookup helper allows for dynamic parameter resolution using Handlebars variables. It can be used to look up properties of object based on data from the input.
In your specific example, you'd probably want to store your people and properties iterations in a block parameter (e.g., named |person| and |property|), as well as using ../ on your inner loop since the context has changed.
Putting that all together for you example, the HBS markup might look like:
<table>
<thead>
<tr>
{{#each properties as |property index|}}
<th><span>{{property}}</span></th>
{{/each}}
</tr>
</thead>
<tbody>
{{#each people as |person|}}
<tr>
{{#each ../properties as |property|}}
<th>{{lookup person property}}</th>
{{/each}}
</tr>
{{/each}}
</tbody>
</table>
See this playground link for the resulting HTML as well.
I know how can i use if else statement or for loop using .ejs file but i need to change code in .hbs file and i am new with this.Please help me with below example in which i have used .ejs file i need to convert it in .hbs file but don't know how to change if else and for loop
<!DOCTYPE html>
<html lang="en">
<head>
<title>Fetch using MySQL and Node.js</title>
</head>
<body>
<div class="table-data">
<h2>Display Data using Node.js & MySQL</h2>
<table border="1">
<tr>
<th>S.N</th>
<th>Full Name</th>
<th>Email Address</th>
<th>City</th>
<th>Country</th>
<th>Edit</th>
<th>Delete</th>
</tr>
<%
if(userData.length!=0){
var i=1;
userData.forEach(function(data){
%>
<tr>
<td><%=i; %></td>
<td><%=data.fullName %></td>
<td><%=data.emailAddress %></td>
<td><%=data.city %></td>
<td><%=data.country %></td>
<td>Edit</td>
<td>Delete</td>
</tr>
<% i++; }) %>
<% } else{ %>
<tr>
<td colspan="7">No Data Found</td>
</tr>
<% } %>
</table>
</div>
</body>
</html>
I have used below code but it is not working as i am new i need your guidence
#76484 i have used this ``` {{#if userData.length != 0 }}
{{var i =1;}}
{{userData.forEach(function(data))}}
<tr>
<td>{{=i;}}</td>
<td>{{= data.fullName}}</td>
<td>{{= data.emailAddress}}</td>
<td>{{= data.city}}</td>
<td>{{= data.country}}</td>
<td>{{= data.Dimension_4_Score}}</td>
<td>{{= data.Total_Score_Persentage}}</td>
</tr>
{{i++; })}}
{{else{} }
<tr>
<td colspan="7">No Data Found</td>
</tr>
{{}}}
</table>
</div>
</body> ``` but it is not working
The primary difference between your embedded JS example and Handlebars is that Handlebars does not execute arbitrary JavaScript, like your .forEach loop. Instead, Handlebars provides helpers to allow you to do things like conditionals and iteration.
First, we will tackle your condition, if (userData.length != 0). Handlebars has a #if helper which we could use to check if userData has a truth (greater than 0) length. The result would be:
{{#if userData.length}}
{{! TODO: output each user data}}
{{else}}
<tr>
<td colspan="7">No Data Found</td>
</tr>
{{/if}}
Secondly, Handlebars has an #each helper which is used for looping over collections as you are doing with your userData.forEach(function(data) { /*...*/ } code. For your purposes, the syntax would be:
{{#each userData}}
<tr>
<td>{{ #index }}</td>
<td>{{ fullName }}</td>
<td>{{ emailAddress }}</td>
<td>{{ city }}</td>
<td>{{ country }}</td>
<td>Edit</td>
<td>Delete</td>
</tr>
{{/each}}
Notice how we are evaluating the properties of each object in our userData array. There is no =. We just wrap the property name in double-handlebars, like {{ fullName }}. Handlebars handles the execution context within the #each so that we are always referring to the current iteration of our array.
Also notice the {{ #index }}. This is a special variable provided by Handlebars to give us the current iteration index within our #each loop. It is zero-index, so our output will be slightly different from your ejs example because you initialized your counter at 1.
Unfortunately, if we want our indexes to be one-based, we will have to write a custom helper to this. Our helper would just need to take a number, #index, and increment it by 1. It would look like:
Handlebars.registerHelper('increment', function (num) {
return num + 1;
});
And we would update our template to make use of it:
{{increment #index }}
I have created a fiddle with the final example for your reference.
Is it possible to auto-print the fields of a Meteor collection using helpers without specifying them?
Let's say I start having a helper that returns the collection of objects stored in a table, as follows:
{{ #each CollectionData }}
<thead>
<tr>
<th>Code</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<Tr class="object-row">
<Td> {{code}} </ td>
<Td> {{description}} </ td>
</tr>
</tbody>
...
{{/each}}
Now i specify an "object schema" for each collection to set which field i want to auto-print, pseudo example:
// Items is the name of the possible collection
Schema.items var = {
fields {
code: {
columnName: "code",
show: false,
},
description: {
columnName: "description",
show: false,
},
otherField {
columnName: "foo",
show: false,
}
}
}
Now, I would make the helper to auto-generate the table columns and values of a collection field where the show check is true, without having to manually specify {{code}}, {{description}} and so on, pseudo example:
{{ #each CollectionData }}
<thead>
<tr>
{{print each column where show check is == true, without manually specifing any name}}
</tr>
</thead>
<tbody>
<Tr class="object-row">
{{print the value of the column, for this record, where show check is == true, without specifing its name}}
</tr>
</tbody>
...
{{/each}}
Is there any way to do that?
The simpliest way would be to create a template for each TD, something like
<thead>
<tr>
{{#each fetchColumnHeaders}}
{{> columnHeader }}
{{/each}}
</tr>
</thead>
{{ #each CollectionData }}
<tbody>
<Tr class="object-row">
{{#each fetchColumnItems}}
{{> columnItem}}
{{/each}}
</tr>
</tbody>
{{/each}}
<template name="columnHeader">
<th>{{label}}</th>
</template>
<template name="columnItem">
<td>{{label}}</td>
</template>
And then you can write template helpers to return the column headers, and the various items based on your schema
I'm very new to smarty and I'm trying to figure out a way to hide questions under each section title in a long form. I would need to add some id or class to the section name and some div to wrap to the questions under this specific section title so I can target them in css or js, but I'm breaking my head to find a way to do that with smarty.
Here is my code:
{if !empty($questionList)}
{foreach from=$questionList key='section' item='questions'}
{if !empty($section) }
<tr class="ow_tr_first"><th colspan="3" class="section_label">{text key="base+questions_section_`$section`_label"}</th></tr>
{/if}
{foreach from=$questions item='question' name='question'}
<tr class="{cycle values='ow_alt1,ow_alt2'} {if $smarty.foreach.question.last}ow_tr_last{/if}">
<td class="ow_label">
{label name=$question.name}
</td>
<td class="ow_value">
{input name=$question.name}
<div style="height:1px;"></div>
{error name=$question.name}
</td>
</tr>
{/foreach}
<tr class="ow_tr_delimiter"><td></td></tr>
{/foreach}
{/if}
Any help would be awesome :)
You can try to use the current iteration of the first foreach to create unique identifiers/classes:
i.e.
{foreach from=$questionList key='section' item='questions' name='loop'}
{if !empty($section) }
<tr class="ow_tr_first"><th colspan="3" class="section_label" id="question{$smarty.foreach.loop.iteration}">{text key="base+questions_section_`$section`_label"}</th></tr>
{/if}
<tr class="question{$smarty.foreach.loop.iteration}_child {cycle values='ow_alt1,ow_alt2'} {if $smarty.foreach.loop.last}ow_tr_last{/if}">
So you willl end up with something like this:
<tr><th class="section_label" id="question1"></th></tr>
<tr class="question1_child">....</tr>
<tr class="question1_child">....</tr>
<tr class="question1_child">....</tr>
<tr><th class="section_label" id="question2"></th></tr>
<tr class="question2_child">....</tr>
<tr class="question2_child">....</tr>
<tr class="question2_child">....</tr>
and so on. That would be quite easy to target with css or javascript, i.e. hiding all .question1_child or showing all #id_name+'_child' when a certain .section_label is pressed
i have a template as below
<script id="ActionTemplate" type="text/x-jquery-tmpl">
<tr>
<td> <a href="#" OnClick="setActionId(${action_id}, ${project_id}, ${merchant_id}, ${channel_id}, ${customer_id})" >${action_id}</a></td>
<td>${priority} </td>
<td>${date_to_display} </td>
<td> ${date_from}</td>
<td>${action_title} </td>
<td> ${status()} (${percentage_completed}%)</td>
<td> ${hours}</td>
<td>${contactFrom} </td>
<td>${contactTo} </td>
</tr>
</script>
in above ${status()} calls the function status which returns a string like this
<script type="language/javascript">
function status(){
return "some_string";
}
</script>
my problem is i hav to send a value from template where the status function is called..value like ${action_status}...
all the values that are in the template like ${priority},${hours},etc are binded to template in a pagemethod...
need a solution
You can pass values from your data to function using the $data keyword. Change the following line in your template like this :
<td> ${status($data.action_status)} (${percentage_completed}%)</td>
assuming 'action_status' is the correct property name from your data...
Update: Here's the link to the api. Look down for the section "Evaluating Expressions and Functions"