Handlebars - accessing `this` within a conditional statement with #root - handlebars.js

Is there any way to access this within a conditional?
To explain a bit more… I have a loop over some items. I want to conditionally show the price if another value is set to something.
{
"firstName": "Terry",
"showPrice": "yes",
"items": [
{ "itemName": "Item 1", "itemPrice": "23.99" },
{ "itemName": "Item 2", "itemPrice": "50.99" }
]
}
{{#each items }}
<p>{{ this.itemName }}</p>
{{#equals #root.showPrice "yes"}}
<p>{{ this.itemPrice }}</p>
{{/equals}}
{{/each}}
The issue seems to be due to going back to the #root to check against the showPrice value, it then breaks this being accessible.
I've tried things like:
{{ this.itemPrice }} // doesn't work
{{ #root.this.itemPrice }} // doesn't work
{{ #root.items.this.itemPrice }} // doesn't work
{{ #root.items.[0].itemPrice }} // can now access, but only the 0 index
{{ #root.items.#index.itemPrice }} // doesn't work
Does anyone have any ideas?

Related

AngularJS add css class if item selector variable is true

I have an item selector directive and I want to add a test for the selected item : if it's archived I have to add a css class.
.directive-items-selector{ ng_click: "openItemsSelector( $event )" }
.wrapper
%ui_select.ui-select{ ng: { model: "input.model", disabled: "disabled",
change: "itemSelectModelChanged()" },
search_enabled: "{{ options.searchable }}" }
%ui_select_match.ui-select-match{ items_selector_match: '',
placeholder: "{{ input.placeholder }} ",
allow_clear: "{{ options.clearable }}",
title: "{{ $select.selected.label }}" }
%i.fa{ ng_class: 'icon' }
{{ $select.selected.label }}
{{$select.selected.object.is_archived}}
%ui_select_choices.ui-select-choices{ repeat: "item.id as item in input.filteredItems track by item.id",
refresh: "reloadItems( $select.search )",
refresh_delay: '{{ input.filterDelay }}' }
.item{ ng_attr_title: "{{ ::item.label }}" }
.item-label {{ ::item.label }}
%small.item-details {{ ::item.details }}
.items-selector-actions
%a.pointer.action{ ng: { if: 'linkToModal', click: 'openDetails()', disabled: "!model" }}
{{ 'btn.details' | translate }}
%a.pointer.action{ ng: { if: 'createButton && klassName && !disabled', click: 'createItem()' }}
{{ 'btn.new' | translate }}
the {{$select.selected.object.is_archived}} return true if the item is archived, I don't know how to add this css class ! any help
You can us the ng-class directive like this:
ng-class="{'class-false' : selected.object.is_archived, 'class-true' : }"
https://docs.angularjs.org/api/ng/directive/ngClass

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.

Add array elements into variable in Twig

I stored some settings in array in Twig and I need to store them into some variable so I can print it. My array contains some data attributes like this:
{% set data = {
visible: { data: "data-visible-items", value: options.visible_items },
scroll: { data: "data-itemes-scroll", value: options.items_to_scroll },
speed: { data: "data-animation-speed", value: options.animation_speed },
infinite: { data: "data-infinite", value: options.infinite },
autoplay: { data: "data-autoplay", value: options.autoplay_enable },
interval: { data: "data-autoplay-interval", value: options.autoplay_interval },
hover: { data: "data-autoplay-hover", value: options.autoplay_hover },
} %}
Simply I want to store everything from array in one variable, in this variable it's need to be stored like this (separator is space) for example:
data-visible-items="5" data-items-scroll="2" data-animation-speed="400" data-infinite="0" data-autoplay="1" data-autoplay-interval="3000" data-autoplay-hover="1"
So, if the variable is for example attributes I just want to print it like this:
<div{{ attributes}}>
// Content
</div>
I wrote for loop like this:
{% for item in data %}
{{ item.data }} {{ item.value }}
{% endfor %}
and it will print each data and value, but how to store this in the variable in the way I described above?
If you want to store into a variable you can do this:
{% for item in data %}
{% set myvar = item.data ~ ' ' ~ item.value %}
{% endfor %}
If you want to transform that array you could make use of a Twig_Filter or Twig_Function
just chain http_build_query
PHP
$twig->addFunction(new Twig_SimpleFunction('http_build_query', http_build_query', ['is_safe' => [ 'html', ],]));
Twig
<div{{ http_build_query(attributes, '', ' ') }}>
Create the string yourself with a foreach
PHP
$twig->addFilter(new Twig_SimpleFilter('build_attribute_list', function (array $array) {
$str = '';
foreach($array as $key => $val) $str .= ' '.$key.'="'.$val.'"';
return $str;
}, ['is_safe' => ['html'],]);
Twig
<div{{ attributes|build_attribute_list }}>
(edit) Needless to say you can store the output in a variable as well
{% set my_var = attributes|build_attribute_list %}
{{ my_var }}

Meteor: Querying a collection based on a URL parameter

I am trying display the unique profile of a babysitter (i.e: babysitter username, city, postal code, etc ... ) from a schema/collection called "Babysitters" .
The URL correctly contains the babysitter unique _id, say:
http://localhost:3000/test/PqMviBpYAmTA2b5ec
but I don't manage to retrieve all the other fields.
meteor question - screenshot
I have tried querying the MongoDB in two files: routes.js and the template test.js
1) in routes.js
Router.route('/test/:_id', {
name: 'test',
data: function () {
return Babysitters.findOne({ _id: this.params._id });
}
});
2) in test.js
Template.test.helpers({
data: function () {
//sitterusername = this.params.sitterusername;
//console.log(this.params._id );
return Babysitters.findOne( { _id: this.params._id });
}
});
the html file: test.html
<template name="test">
{{#with data}}
<ul>
<li><img src="/" {{photourl}} height="100" width="100" ></li>
<li>Babysitter username: {{ sitterusername }}</li>
<li>Presentation: {{ presentation }}</li>
<li>City: {{ city }}</li>
<li>Postal Code: {{ postalcode }}</li>
<li>Mother tongue: {{ mothertongue }}</li>
<li>Languages spoken {{ languagesspoken }}</li>
<li>Experience {{ experience }}</li>
<li>Homework help: {{ homeworkhelpavailable }}</li>
<li>Hourly wages: {{ hourlywages }} €/h</li>
</ul>
{{/with}}
</template>
I have tried all sorts of ways but the Collection fields never appear in the HTML file.
Thanks for your help, a newbie here.
K.
Most likely you are not publishing all Babysitters to the client so your .findOne() returns nothing.
This is a common router pattern where you want to display a single document which is not normally published. A good way to solve this in i-r is to waitOn a subscription to the individual document:
waitOn: function(){
return Meteor.subscribe('oneBabysitter', this.params._id);
}
On the server, publish:
Meteor.publish('oneBabysitter',function(_id){
return Babysitters.find(_id);
});
Note that even though this publication is only going to return a single document you still have to do a .find() and not a .findOne() because publications need to return a cursor or array of cursors, not objects.

RactiveJS iterator (for) structure

I'm wondering if , for example I have number_of_fields => 2 and I'd like to show up two input texts like this:
{{ # number_of_fields }}
<input type="text" />
{{ / fields }}
Doing this, obviously results in one input since the parameter I'm passing (number_of_fields) is actually one simple element. What I'm trying to accomplish is an "add new field" feature in a CV generator, and I'd like doing it "automatically" with ractive instead of just adding a new element with JS manually on-click.
I found a way which I consider to be really useful. Even if there would be any "easy" or natural way to do a for in RactiveJS we may still find ourselves in need of binding or controlling the data so if we would have this :
{{ # fields_number:num }}
{{ / fields }}
That's quite bad of a method for getting those values binded, and I am sure we all agree. Now, what I've asked a while ago here https://stackoverflow.com/questions/25460380/ is quite the same situation.
But then it struck me !
I thought about having an array of x null values where x would be the number of inputs in my case.
...
data : {
groups : [ 'group1', 'group2', ...],
fields : {
group1 : [ null, null ],
group2 : [ null, null, null ],
...
}
...
Then it'll be way easier to bind the data, directly into these values like this:
{{ # groups:number }}
<div id="{{ . }}">
{{ # fields[ groups[ number ] ]:index }}
<input type="text" value="{{ fields[ groups[ number ] ][ index ] }}" />
{{ / fields }}
</div>
{{ / groups }}
Now, you have a ractive.get( 'fields' ) full binded data :). Hope this helps !

Resources