Search code examples
javascripthandlebars.jsractivejs

Change function on-click using if in the handlebars


I have a boolean variable that is set in the JS and I want to change the function a button calls when an on-click event is fired. Below are the two ways I've tried.

<button type="button" {{#if variable}}on-click="funcOne"{{else}}on-click="funcTwo"{{/if}}>Click Me</button>

<button type="button" on-click="{{#if variable}}funcOne{{else}}funcTwo{{/if}}>Click me</button>

Is this not possible in the handlebars, would I instead have to call one function that checks the variable and then call one of the two functions from there?


Solution

  • The first example is something we have an open issue for - currently, 'conditional directives' (i.e. directives such as on-click) aren't supported inside mustache sections.

    There are two different ways we can make this work. The first is with proxy events:

    var ractive = new Ractive({
        el: 'main',
        template: '#template',
        data: {
            variable: true
        }
    });
    
    ractive.on({
        funcOne: function () { alert( 'one' ); },
        funcTwo: function () { alert( 'two' ); }
    });
    <script src="//cdn.jsdelivr.net/ractive/0.7.3/ractive-legacy.min.js"></script>
    
    <main></main>
    
    <script id='template' type='text/ractive'>
        <label>
            <input type='checkbox' checked='{{variable}}'/> variable ({{variable}})
        </label>
        
        <button type="button" on-click="{{#if variable}}funcOne{{else}}funcTwo{{/if}}">Click me</button>
    </script>

    The click event is translated into either a funcOne event or a funcTwo event depending on variable - we just need to listen for that event with ractive.on, the same as you might listen for the click event with node.addEventListener.

    The alternative approach is to call a method directly. You can't choose a method conditionally (i.e. on-click='{{#if variable}}funcOne(){{else}}funcTwo(){{/if}}'), but you can do it using regular JavaScript:

    var ractive = new Ractive({
        el: 'main',
        template: '#template',
        data: {
            variable: true
        },
        funcOne: function () { alert( 'one' ); },
        funcTwo: function () { alert( 'two' ); },
        callMethod: function ( name ) {
            this[name]();
        }
    });
    <script src="//cdn.jsdelivr.net/ractive/0.7.3/ractive-legacy.min.js"></script>
    
    <main></main>
    
    <script id='template' type='text/ractive'>
        <label>
            <input type='checkbox' checked='{{variable}}'/> variable ({{variable}})
        </label>
        
        <button type="button" on-click="callMethod(variable?'funcOne':'funcTwo')">Click me</button>
    </script>