Handlebars: native inline conditional expression or equivalent? - if-statement

How can I have an inline conditional expression in a Handlebars template?
There is a way to do that within a "native" way? I mean, without registering a custom helper?
For example, I've been playing with the code (with the parenthesis and without them):
<select name="alignment">
<option value="left" {{ #if (options.text_alignment == 'left') }}selected="selected"{{ /if }}>Left</option>
<option value="center" {{ #if (options.text_alignment == 'center') }}selected="selected"{{ /if }}>Center</option>
<option value="right" {{ #if (options.text_alignment == 'right') }}selected="selected"{{ /if }}>Right</option>
</select>
but it doesn't work at all and throws the error:
Error: Parse error on line 20:
...ion value="left" {{ #if (options.text_al
-----------------------^
Expecting 'ID', 'DATA', got 'INVALID'
[Break On This Error]
throw new Error(str);
So, how I can have an inline conditional statement in the form of if/else structures or the classic ternary operator (var == value)?'yes':'no'
Thanks in advance.

Finally, I was able to accomplish that but I've to say it, in a not nice way :(
I registered a custom helper like the following:
// Need to mark selected option inside a select.
Handlebars.registerHelper('select', function(variable, value) {
if (variable == value) {
return new Handlebars.SafeString('selected=selected');
}
else {
return '';
}
});
This custom helper can be used like that:
{{select option 'right'}}
where option is the variable to be tested and 'right' the value against it is tested.
If later anyone come with a nice solution that works also for radios & checkboxes please, add the answer that I will be happy to vote up them :D

inline if statement:
<div class="message {{if isImportant 'important' 'unimportant'}}"></div>

As far as I know, this is the only way you can do it without registering a custom helper.
Handlebars.js Else If

Related

How to preselect an option in an embedded HTML form?

I try to preselect an option of a select in an embedded HTML form in Camunda Tasklist, but always the first option is preselected.
I followed Binding to a Process Variable:
Binding to a Process Variable
A select box can be bound to a process variable using the cam-variable-name directive:
<select cam-variable-name="foo" cam-variable-type="String">
<option>bar</option>
<option>zar</option>
</select>
Research
I read also CAM-3173:
select box doesn't show the correct option
If I set the value of variable by a select box on the start form, the next task form didn't show the option that has been choosen in the start form. It uses the same select box.
but I use Camunda 7.9 and the problem is fixed since version 7.2.3.
HTML
<form>
<select cam-variable-name="variable" cam-variable-type="String">
<option value="option1">option1</option>
<option value="option2">option2</option>
</select>
</form>
Result
option1 is preselected. I checked the process variable before entering the user task and it contains option2.
What did I wrong? If the bug still exists, is there any work-around?
I found a work-around, see Camunda Reference:
Implementing Custom Fields
The following is a small usage example which combines some of the features explained so far. It uses custom JavaScript to implement a custom interaction with a form field which does not use any cam-variable-* directives.
It shows how custom scripting can be used for
declaring a variable to be fetched from the backend,
writing the variable’s value to a form field,
reading the value upon submit.
[...]
The above example uses jQuery for interacting with the HTML controls. If you use AngularJS, you can also populate the $scope in the variables-fetched callback and read the values from the $scope in the submit callback:
My changed HTML:
<form>
<script cam-script type="text/form-script">
camForm.on('form-loaded', function() {
camForm.variableManager.fetchVariable('variable');
});
camForm.on('variables-fetched', function() {
$scope.variable = camForm.variableManager.variable('variable');
});
camForm.on('submit', function() {
camForm.variableManager.variableValue('variable', $scope.variable);
});
</script>
<select data-ng-model="variable">
<option value="option1">option1</option>
<option value="option2">option2</option>
</select>
</form>

Testing multiple conditions (Else if) when using the ternary operator in razor view

I have a list collection of umbraco pages and i want to loop through checking if a bool property is true and if so i want to apply a specific class to the div
How can i write an else if ternary operator in razor to apply a class to to a div. If i wasnt using ternary then it would look like this
if package.GetPropertyValue<bool>("test")
{
<div class="test1"></div>
}
else if (package.GetPropertyValue<bool>("test1"))
{
<div class="test1"></div>
}
else if (package.GetPropertyValue<bool>("test2"))
{
<div class="test2"></div>
}
in my razor view it would be something like as follows (but not right)
<div class="#(package.GetPropertyValue<bool>("test") ? "test" : package.GetPropertyValue<bool>("test1") ? "test1" : "test2" )"></div>
Can this be done or can someone suggest how I can apply a specific class to that div when a specific condition is met?
many thanks
paul
Yes, you can nest ternary operators, but be careful going too nuts, or you can render the code quite hard to read. You could do something like:
#{
var css = package.GetPropertyValue<bool>("test") ? "test" :
package.GetPropertyValue<bool>("test1") ? "test2" :
package.GetPropertyValue<bool>("test2") ? "test3" : "";
}
<div class="#css"></div>
However, this seems like a bad bit of design. What if they want another class later on? You'd have too add another level of nesting to the ternary operator, and again the next time etc. If this property is just for setting the style, why not have a single property with a dropdown that lets them choose the style instead, eliminating the need for the nested ternary operators.

Handlebars / Mustache - Missing helper: 'partial'

I'm trying to get to grips with Handlebars / Mustache in order to build an atomic design (à la PatternLab).
I'm doing ok but I've stumbled trying to define a partial.
Here's my example:
{{#partial 'selectOption' }}
<option value="{{value}}" label="{{label}}" {{#disabled}}disabled{{/disabled}} {{#selected}}selected{{/selected}}>{{text}}</option>
{{/partial}}
{{#.}}
<select name="{{name}}" id="{{ID}}" class="selectField selectList {{cssString}}" {{{htmlAttributes}}}>
{{#optGroups}}
<optGroup {{#disabled}}disabled{{/disabled}} label="{{label}}">
{{#options}}
{{> selectOption}}
{{/options}}
</optGroup>
{{/optGroups}}
{{#options}}
{{> selectOption}}
{{/options}}
</select>
{{/.}}
What I'm trying to achieve is creating a partial for the 'option' tag. I've been crawling all over Google and SO all afternoon trying to get my head 'round this one and this is the closest I've got.
However, when I try to run this I get: Uncaught Error: Missing helper: 'partial'
I thought that partials were built-in to handlebars but if not I guess I have to install it as a helper? I've tried to work that out too but to no avail.
The examples on the handlebars site don't seem to work (or I'm copying them into the wrong places).
Any help?
OK, so fresh eyes and a good nights sleep solves the problem again.
I was somehow using v2.0.0 of handlebars instead of the latest (v4.0.0).
After updating I can now create an inline partial using the following syntax:
{{#*inline "selectOption"}}
<option value="{{value}}" label="{{label}}" {{#disabled}}disabled{{/disabled}} {{#selected}}selected{{/selected}}>{{text}}</option>
{{/inline}}
Hope this is of use to someone else.

JsRender if statement support

Does jsRender supports if statments like below ?
{{ if val > 1 }}
....
{{ /if }}
I couldn't find any examples.
Also I understand that there is a variant of using helper functions.
Yes, see www.jsviews.com/#iftag.
In fact you can write {{if pathOrExpr}} where path can be any combination of 'data paths' and reqular javascript operators etc.
The example shows {{if members && members.length}} and similarly you can do all the expected conditional expressions such as:
address.zip === '88888', or:
foo.count < 3 && foo.total >= bar.total,
etc. etc.

if else statement in AngularJS templates

I want to do a condition in an AngularJS template. I fetch a video list from the Youtube API. Some of the videos are in 16:9 ratio and some are in 4:3 ratio.
I want to make a condition like this:
if video.yt$aspectRatio equals widescreen then
element's attr height="270px"
else
element's attr height="360px"
I'm iterating the videos using ng-repeat. Have no idea what should I do for this condition:
Add a function in the scope?
Do it in template?
Angularjs (versions below 1.1.5) does not provide the if/else functionality . Following are a few options to consider for what you want to achieve:
(Jump to the update below (#5) if you are using version 1.1.5 or greater)
1. Ternary operator:
As suggested by #Kirk in the comments, the cleanest way of doing this would be to use a ternary operator as follows:
<span>{{isLarge ? 'video.large' : 'video.small'}}</span>
2. ng-switch directive:
can be used something like the following.
<div ng-switch on="video">
<div ng-switch-when="video.large">
<!-- code to render a large video block-->
</div>
<div ng-switch-default>
<!-- code to render the regular video block -->
</div>
</div>
3. ng-hide / ng-show directives
Alternatively, you might also use ng-show/ng-hide but using this will actually render both a large video and a small video element and then hide the one that meets the ng-hide condition and shows the one that meets ng-show condition. So on each page you'll actually be rendering two different elements.
4. Another option to consider is ng-class directive.
This can be used as follows.
<div ng-class="{large-video: video.large}">
<!-- video block goes here -->
</div>
The above basically will add a large-video css class to the div element if video.large is truthy.
UPDATE: Angular 1.1.5 introduced the ngIf directive
5. ng-if directive:
In the versions above 1.1.5 you can use the ng-if directive. This would remove the element if the expression provided returns false and re-inserts the element in the DOM if the expression returns true. Can be used as follows.
<div ng-if="video == video.large">
<!-- code to render a large video block-->
</div>
<div ng-if="video != video.large">
<!-- code to render the regular video block -->
</div>
In the latest version of Angular (as of 1.1.5), they have included a conditional directive called ngIf. It is different from ngShow and ngHide in that the elements aren't hidden, but not included in the DOM at all. They are very useful for components which are costly to create but aren't used:
<div ng-if="video == video.large">
<!-- code to render a large video block-->
</div>
<div ng-if="video != video.large">
<!-- code to render the regular video block -->
</div>
Ternary is the most clear way of doing this.
<div>{{ConditionVar ? 'varIsTrue' : 'varIsFalse'}}</div>
Angular itself doesn't provide if/else functionality, but you can get it by including this module:
https://github.com/zachsnow/ng-elif
In its own words, it's just "a simple collection of control flow directives: ng-if, ng-else-if, and ng-else." It's easy and intuitive to use.
Example:
<div ng-if="someCondition">
...
</div>
<div ng-else-if="someOtherCondition">
...
</div>
<div ng-else>
...
</div>
You could use your video.yt$aspectRatio property directly by passing it through a filter, and binding the result to the height attribute in your template.
Your filter would look something like:
app.filter('videoHeight', function () {
return function (input) {
if (input === 'widescreen') {
return '270px';
} else {
return '360px';
}
};
});
And the template would be:
<video height={{video.yt$aspectRatio | videoHeight}}></video>
In this case you want to "calculate" a pixel value depending of an object property.
I would define a function in the controller that calculates the pixel values.
In the controller:
$scope.GetHeight = function(aspect) {
if(bla bla bla) return 270;
return 360;
}
Then in your template you just write:
element height="{{ GetHeight(aspect) }}px "
I agree that a ternary is extremely clean. Seems that it is very situational though as somethings I need to display div or p or table , so with a table I don't prefer a ternary for obvious reasons. Making a call to a function is typically ideal or in my case I did this:
<div ng-controller="TopNavCtrl">
<div ng-if="info.host ==='servername'">
<table class="table">
<tr ng-repeat="(group, status) in user.groups">
<th style="width: 250px">{{ group }}</th>
<td><input type="checkbox" ng-model="user.groups[group]" /></td>
</tr>
</table>
</div>
<div ng-if="info.host ==='otherservername'">
<table class="table">
<tr ng-repeat="(group, status) in user.groups">
<th style="width: 250px">{{ group }}</th>
<td><input type="checkbox" ng-model="user.groups[group]" /></td>
</tr>
</table>
</div>
</div>
<div ng-if="modeldate==''"><span ng-message="required" class="change">Date is required</span> </div>
you can use the ng-if directive as above.
A possibility for Angular:
I had to include an if - statement in the html part, I had to check if all variables of an URL that I produce are defined. I did it the following way and it seems to be a flexible approach. I hope it will be helpful for somebody.
The html part in the template:
<div *ngFor="let p of poemsInGrid; let i = index" >
<a [routerLink]="produceFassungsLink(p[0],p[3])" routerLinkActive="active">
</div>
And the typescript part:
produceFassungsLink(titel: string, iri: string) {
if(titel !== undefined && iri !== undefined) {
return titel.split('/')[0] + '---' + iri.split('raeber/')[1];
} else {
return 'Linkinformation has not arrived yet';
}
}
Thanks and best regards,
Jan
ng If else statement
ng-if="receiptData.cart == undefined ? close(): '' ;"