how to use handlebars conditional helpers? - if-statement

I have a Handlebars template with multiple iff blocks. iff is a custom helper for comparing values. The template compiles, but oo applying it i get no output and no errors.
Please what am I doing wrong?
iff helper
Handlebars.registerHelper("iff", function (v1, operator, v2, options) {
switch (operator) {
case '==':
return (v1 == v2) ? options.fn(this) : options.inverse(this);
case '===':
return (v1 === v2) ? options.fn(this) : options.inverse(this);
case '<':
return (v1 < v2) ? options.fn(this) : options.inverse(this);
case '<=':
return (v1 <= v2) ? options.fn(this) : options.inverse(this);
case '>':
return (v1 > v2) ? options.fn(this) : options.inverse(this);
case '>=':
return (v1 >= v2) ? options.fn(this) : options.inverse(this);
case '&&':
return (v1 && v2) ? options.fn(this) : options.inverse(this);
case '||':
return (v1 || v2) ? options.fn(this) : options.inverse(this);
case '!=':
return (v1 != v2) ? options.fn(this) : options.inverse(this);
case '!==':
return (v1 !== v2) ? options.fn(this) : options.inverse(this);
default:
return options.inverse(this);
}
});
template
{{#each message}}
{{#iff type '==' -1}}
<div class='sb-date'>{{text}}</div>
{{/iff}}
{{#iff type '==' 1}}
<div class='sb sb-text sb-{{dir}}'>{{text}}<div class="sb-time">{{time}}</div></div>
{{/iff}}
{{#iff type '==' 5}}
<div class='sb sb-text sb-{{dir}}'>{{text}}<div class="sb-time">{{time}}</div></div>
{{/iff}}
{{#iff type '==' 6}}
<div class='sb sb-text sb-{{dir}}'>{{text}}<div class="sb-time">{{time}}</div></div>
{{/iff}}
{{#iff type '==' 2}}
<div class='sb sb-image sb-{{dir}}'><img alt="" src="media/{{text}}" /><div class="sb-time">{{time}}</div></div>
{{/iff}}
{{#iff type '>' 2}}
<div class='sb sb-file sb-{{dir}}'>media/{{text}}<div class="sb-time">{{time}}</div></div>
{{/iff}}
{{/each}}

Found the solution.
When passing an array use: {{#each this}}

Related

Conditional #click with a method in vuejs

This is my for loop:
<li v-for="(crumb, index) in breadcrumbs" :class="{ 'is-active' : index==breadcrumbs.length-1 }">
{{ crumb.name }}
</li>
#click="methodName" shouldn't be available for the last iteration.
I can check the last iteration with index==breadcrumbs.length-1
Is this possible using apply v-if?
There is a possibility by defining the event handler this way:
v-on="condition ? { eventName: () => handler } : {}"
The ?: operator can be used as a shortcut for an if...else statement
In your case it would be like this:
<li v-for="(crumb, index) in breadcrumbs" :class="{ 'is-active' : index==breadcrumbs.length-1 }">
<a href="javascript:void(0)" v-on="index < breadcrumbs.length-1 ? { click: () => methodName(parms) } : {click: ($event) => $event.preventDefault() }" >{{ crumb.name }}</a>
</li>
Small fiddle

How do I get the original value in handlebars register helpers?

I have moved into latest Ember version 1.9.1 and Handlebars version 2.0.0. In this, I am getting an error like "Usage of Ember.Handlebars.get is deprecated, use a Component or Ember.Handlebars.makeBoundHelper instead."
I have a code like this,
Handlebars.registerHelper('ifCond', function (temp_v1, operator, temp_v2, options) { // No I18N
var v1,v2;
v1 = Ember.Handlebars.get(this, temp_v1, options);
v2 = Ember.Handlebars.get(this, temp_v2, options);
if( v1 == undefined ){
v1 = temp_v1;
}
if( v2 == undefined ){
v2 = temp_v2;
}
switch (operator) {
case '==':
return (v1 == v2) ? options.fn(this) : options.inverse(this);
case '!=':
return (v1 != v2) ? options.fn(this) : options.inverse(this);
default:
return options.inverse(this);
}
});
Here, I need to check the given string value is equal or not. If I remove the "Handlebars" in Ember.Handlebars.get(this, temp_v1, options), that deprecation error will be gone. But I couldn't get the original value of temp_v1.
JSBIN LINK: JSBIN LINK
With minimum modifications to the code posted, a possible solution could be along the lines of setting a properly modified itemController to the {{each}} helper and then retrieve the targeted property from this controller.
This approach strongly couples the itemController structure (i.e. the item property and toString function) to the hbs template structure (i.e. the item property defined within the each helper), which is not that bad as long as the helper remains independent and reusable.
Example,
http://emberjs.jsbin.com/geqezicaki/1/edit?html,js
hbs
<script type="text/x-handlebars" data-template-name="index">
<ul>
{{#each item in model itemController="test"}}
{{#ifCond item '==' red}}
<li>{{item}}</li>
{{/ifCond}}
{{/each}}
</ul>
</script>
js
Handlebars.registerHelper('ifCond', function (temp_v1, operator, temp_v2, options) { // No I18N
var v1,v2;
//v1 = Ember.get(this, temp_v1, options);
//v2 = Ember.get(this, temp_v2, options);
v1 = options.data.view.get("controller").get(temp_v1);
v2 = options.data.view.get("controller").get(temp_v2);
if( v1 === undefined ){
v1 = temp_v1;
}
if( v2 === undefined ){
v2 = temp_v2;
}
switch (operator) {
case '==':
return (v1 == v2) ? options.fn(this) : options.inverse(this);
case '!=':
return (v1 != v2) ? options.fn(this) : options.inverse(this);
default:
return options.inverse(this);
}
});
App.TestController = Em.ObjectController.extend({
item:Em.computed.alias("model"),
toString:function(){return this.get("item");}
});

Handlebars Register Helpers - Sending values from model

I am using a custom handlebars register helper to check conditional operators ( &&, ||, == ) and calling the register helper inside my each helper in my template backed by a model from Route.
But when I am passing the values from a model to the custom helper, the value is not passed to the helper instead the string as such is passed.
Template:
<script type="text/x-handlebars" data-template-name="index">
<ul>
{{#each item in model}}
{{#ifCond item '==' 'red'}}
<li>{{item}}</li>
{{/ifCond}}
{{/each}}
</ul>
</script>
Route:
App.IndexRoute = Ember.Route.extend({
model: function() {
return ['red', 'yellow', 'blue', 'red', 'blue', 'pink'];
}
});
ifCond Register Helper:
Handlebars.registerHelper('ifCond', function (v1, operator, v2, options) {
console.log(v1); //item - Here the value is coming as such and not the model value.
console.log(v2); // red
console.log(operator); // ==
console.log(options);
switch (operator) {
case '==':
return (v1 == v2) ? options.fn(this) : options.inverse(this);
case '===':
return (v1 === v2) ? options.fn(this) : options.inverse(this);
case '<':
return (v1 < v2) ? options.fn(this) : options.inverse(this);
case '<=':
return (v1 <= v2) ? options.fn(this) : options.inverse(this);
case '>':
return (v1 > v2) ? options.fn(this) : options.inverse(this);
case '>=':
return (v1 >= v2) ? options.fn(this) : options.inverse(this);
case '&&':
return (v1 && v2) ? options.fn(this) : options.inverse(this);
case '||':
return (v1 || v2) ? options.fn(this) : options.inverse(this);
default:
return options.inverse(this);
}
});
How do I pass the value from the model to the custom helper.
JSBin --> Link
If you want to retrieve object value you need to fetch it.
v1 = Ember.Handlebars.get(this, v1, options);

Emberjs and jquery restrict textbox values

I have created a textbox which should contain only integers or decimal. Its working fine normally but whem i am linking with emberjs its not working
Here is my jquery
$(function () { alert('test')//This alert is working
$("input[name='sum']").keydown(function (event) {
if (event.shiftKey == true) {
event.preventDefault();
}
if ((event.keyCode >= 48 && event.keyCode <= 57) || (event.keyCode >= 96 && event.keyCode <= 105) || event.keyCode == 8 || event.keyCode == 9 || event.keyCode == 37 || event.keyCode == 39 || event.keyCode == 46 || event.keyCode == 190) {
} else {
event.preventDefault();
}
if($(this).val().indexOf('.') !== -1 && event.keyCode == 190)
event.preventDefault();
});
});
Here is my ember handlebar
{{view Ember.TextField valueBinding="sum_up" name="sum"}}
You can customize Ember.TextField to do this. Ember View supports native browser events..Refer this
App.TestView = Ember.TextField.extend({
keyDown : function (event) {
//Do your stuffs here
});
Fiddle
Hope it helps ..

Is it possible to use function in Handlebars #if?

I have a controller object that's like:
MyApp.objController = Ember.ArrayController.create({
init: function(data) {
data.isValid = function() {
return (data.validity === "valid");
}
this.pushObject(MyApp.MyObj.create(data));
}
});
My view is like:
{{#each MyApp.objController}}
{{#if isValid}}
<some markup>
{{else}}
<some other markup>
{{/if}}
{{/each}}
I was assuming that the if conditional in Handlebars accepts both values and functions, but this doesn't seem to be the case. Is it actually possible, and I'm just doing it wrong?
Handlebars if statements only compares if a value exists, to if it is a falsy value (ie non-existant, 0, an empty string etc.). You have to write a custom helper function.
You could do it like this
Handlebars.registerHelper('isValid', function (value, options) {
if (value == "valid") {
return options.fn(this);
}
return options.inverse(this);
});
This registers a block helper. If the value you pass in evaluates to "valid" it returns the template following the the helper with the current data. If it does not evaluate to valid it returns the template following the else statement with the current data.
Then in your template you could use it like this
{{#each MyApp.objController}}
{{#isValid validity}}
<some markup>
{{else}}
<some other markup>
{{/isValid}}
{{/each}}
Otherwise, if you wanted to abide by the spirit of Handlebars and do a 'logic-less' template, set a flag before you render the template indicating whether or not that data is valid, then use the handlebars if helper with the flag.
You could also possible set up a generic function to handle this and other cases. See my answer in Logical operator in a handlebars.js {{#if}} conditional for an example for a generic if (similar to the above answer)
If you define your isValid as a property, you can use it in your if statement without creating a custom Handlebars helper, see http://jsfiddle.net/pangratz666/Dq6ZY/:
Handlebars:
<script type="text/x-handlebars" data-template-name="obj-template" >
{{view Ember.TextField valueBinding="age" }}
{{#if isValid}}
Si Si.
{{else}}
Nope!
{{/if}}
</script>​
JavaScript:
App.MyObj = Ember.Object.extend({
isValid: function() {
return this.get('age') >= 18;
}.property('age')
});
Ember.View.create({
templateName: 'obj-template',
controller: App.MyObj.create({
age: 21
})
}).append();
​
You could create a custom Handlebars helper to do this.
Try this:
<ul>
{{#each subsites}}
{{#if this}}
<li>{{{WhatIsTheSiteFor this}}}</li>
{{else}}
<li>no found</li>
{{/if}}
{{/each}}
</ul>
The helper function WhatIsTheSiteFor:
Handlebars.registerHelper('WhatIsTheSiteFor', function(siteName) {
var subSiteName = '',
siteNameStr = '';
$.each(siteName, function(i, item) {
siteNameStr += item;
return siteNameStr;
});
if(siteNameStr === 's.gbin1.com') {
subSiteName = 'GB搜索引擎';
}
else if (siteNameStr === 'm.gbin1.com') {
subSiteName = 'GB手机阅读';
}
else if (siteNameStr === 'rss.gbin1.com') {
subSiteName = 'RSS消息订阅';
}
return subSiteName;
});
A demo can be found here: http://www.gbin1.com/gb/networks/uploads/71bb1c1e-0cd3-4990-a177-35ce2612ce81/demo6.html