Is it possible to use function in Handlebars #if?

21,423

Solution 1

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();

Solution 2

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)

Share:
21,423
Jay
Author by

Jay

Updated on February 15, 2020

Comments

  • Jay
    Jay about 4 years

    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?

  • Jay
    Jay over 11 years
    I was hoping for a bit more detail...I haven't done anything with Handlebars in a month so I've forgotten most of what I knew :P. Will come back and accept this when I go back to that part of my project and try it.
  • Jay
    Jay over 11 years
    Sweet! Thanks! Works better than my method of using a computed property
  • jevon
    jevon about 10 years
    It looks like in Ember 1.5.1+ this is no longer an option.
  • Galen
    Galen over 9 years
    Ending in {{/if}} didn't work for me, but ending in {{/isValid}} did. Not sure if this is because this is 2.5 years later or what, but just wanted to throw it out there.
  • Nick Kitto
    Nick Kitto over 9 years
    Yes, this is a typo. Corrected.
  • Jeanno
    Jeanno over 7 years
    Poorly formatted and contextless code. Would be much helpful if explanations are added.