Getting Last Element of Array In Handlebars by Length -1 - handlebars.js

I'm trying to get the last element of an array in handlebars. I was thinking that I could just do:
{{#each names}}
<p>{{ this.[this.length -1] }}</p>
{{/each }}
But that doesn't work. I get nothing.
How can I do this?

Related

Handlebars: Using Parent Variable as a Parameter to a Custom Helper Wrapped in an Each Block

Check out ../billerId below. If I put {{ billerId }} before the {{# each }} block, I can see that billerId is there and defined.
I want to user billerId in my custom helper to see if the option's value should be pre-selected.
<select class="searchbar-control col-6 form-control" id="searchbar-select-biller" style="display:none">
<option value=''>Select a biller...</option>
{{# each billers }}
<option value='{{ _id }}' {{ ifEqual _id ../billerId "selected" "" }} >{{ name }}</option>
{{/ each }}
</select>
Here's the helper code:
ifEqual: function (obj, value, trueString, falseString) {
return ( (obj===value) ? trueString : falseString );
},
I have tried various syntaxes: billerId, ../billerId, ../../billerId, {{ billerId }}.
No luck.
Not exactly an answer, but on researching, I don't think Handlebars allows this type of usage.
Instead, I put the billerId in a hidden span and referenced the span by its id from within javascript. I assigned "selected" from within the script.

CustomHelper inside {{# each}} block

I have a list of "matters." Each matter has an _id and name.
I have a "transaction." Every transaction belongs to a matter by reference to the matter's _id via a transaction.matterId property.
I'm presently working on a user interface to allow making changes to the transaction, including changing the matter to which the transaction is assigned. Like this:
Enter date:
Select a matter: (this is the culprit)
Enter the amount:
I am using handlebars to generate a Bootstrap select input with an option for each matter - i.e., "Select a matter..." This is easily done with handlebars {{ # each }} block helper. All the matters correctly appear as options, and each option's value is correctly assigned. No problem so far...
However, I want the option whose value matches the transaction.MatterId to be pre-selected since this is an update screen. For that, I invoke my custom "IfEquals" helper inside my {{# each }} block. The handlebars template is like this:
<div>Matter: {{ transaction.matterId}}</div> <-- I can see the matterId here.
<div class='form-group'>
<label for="selMatter">Case</label>
<select required id="selMatter" name="matterId" class="form-control">
{{# each matters }}
<option value='{{ _id }}' {{ ifEqual _id ../transaction.matterId "selected" "" }} >{{ name }}</option>
{{/ each }}
</select>
</div>
The custom helper is this:
ifEqual: function (obj, value, trueString, falseString) {
return ( (obj===value) ? trueString : falseString );
}
Let's say the 1st <div> shows a transaction.MatterId of "5." There will be one (and only one) option with a value of "5."
In the handlebars template, I have tried all sorts of possibilities to try to get {{ IfEqual }} to properly compare the 2 values. I tried the transaction.matterId without the "../" to see if it might be a context problem. No luck. I tried using a handlebars subexpression (even with its own helper function). Nope.
I am not getting the proper values inside the {{ IfEqual }} helper, and for that reason, even though the matching <option> is there, I can't make handlebars add the "selected" attribute to it.
Here is what I believe to be the right place to look, but I am not seeing what I am missing. http://handlebarsjs.com/expressions.html
Well, I got it, finally. If anyone comes across this scenario, here's what worked for me:
handlebars template:
<div class='form-group'>
<label for="selMatter">Case</label>
<select required id="selMatter" name="matterId" class="form-control">
{{# each matters }}
{{{ makeOption _id ../transaction.matterId name }}}
{{/ each }}
</select>
</div>
Here's the {{{ makeOption }}} helper:
makeOption: function (optionValue, dataValue, displayText) {
myOption = "<option value='" + optionValue + "'";
if ( optionValue.toString() === dataValue.toString() )
myOption += " selected";
myOption += ">" + displayText + "</option>";
return myOption;
},

Calling a Specific custom_field BigCommerce Stencil

Currently I can get custom fields all or none. Like this
{{#each product.custom_fields}}
{{ id }} : {{ name }} : {{ value }}
{{/each}}
but what if i want to call just one of them by id or name like the below. Is there a way to do that with stencil or otherwise?
{{product.custom_fields.id:4.name}}
You can select a list item by id. {{product.custom_fields.id.4.name}}, however, if you want to select by name you'll need to implement a conditional as #alyss suggested.
See: How do I access an access array item by index in handlebars?
You can use the existing {{if}} helper to accomplish this
{{#if display_name '===' 'material'}}
{{#each product.custom_fields}}
{{id}} : {{name}} : {{value}}
{{/each}
{{/if}}

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.

{{#if foo }}{{ foo}}{{/if}} is there a better way to check for value in handlebars.js? (Quiet Reference Notation)

Is there a better way?
{{#if firstName }} {{ firstName}} {{/if}}
{{#if middleName }} {{ middleName}} {{/if}}
{{#if lastName }} {{ lastName}} {{/if}}
I often have missing data.
You can also use
{{#with firstName}} {{this}} {{/with}}
Best way would be to save the name as an object {name:{first:'James', last:'Bond'}} and then:
{{#with name}}{{last}}, {{first}} {{last}}{{/with}}
With handlebars if the value is null or empty handlebars will spit out an empty string as Nick Kitto mentioned.
so just {{firstName}} {{middleName}} {{lastName}} would be fine. However, if the middle name were blank you'd end up with 2 spaces between the first and last name, that's about the only possible problem I can see.

Resources