Search code examples
javascriptractivejs

RactiveJS template conditional HTML


I am trying to have HTML appear conditionally in ractive template with no success.

As you can see in this JSFiddle the result is not as expected - table is a single row.

My template:

<table border="1">
    <tr>
    {{#list:num}}
        <td>{{.}}</td>
        {{#if num > 0 && num % 2 == 0}}
               </tr><tr>  
        {{/if}}
    {{/list}}
    </tr>
</table>

My Javascript:

var ractive = new Ractive({
    el: "#cont",
    template: "#template",
    data: {
        list: [1, 2, 3, 4, 5, 6]
    }
});

Solution

  • Unlike traditional templating systems, where you're generating an HTML string, each section of a Ractive template must be valid in its own right, otherwise it's impossible to construct the virtual DOM. That means that you can't have </tr><tr> inside a section. (Really, the parser should throw an error - I've raised an issue on GitHub.)

    A different approach would be to group the items, and iterate over the groups:

    var ractive = new Ractive({
        el: "#cont",
        template: "#template",
        data: {
            list: [1, 2, 3, 4, 5, 6]
        },
        computed: {
            grouped: function () {
                var list = this.get( 'list' ),
                    grouped = [],
                    group;
                
                group = [];
                grouped.push( group );
                
                list.forEach( function ( item, i ) {
                    if ( i > 0 && i % 2 == 0 ) {
                        group = [];
                        grouped.push( group );
                    }
                    
                    group.push( item );
                });
                
                return grouped;
            }
        }
    });
    <script src="http://cdn.ractivejs.org/0.6.0/ractive.js"></script>
    
    <script type="text/html" id="template" >
        <table border="1">
            {{#each grouped}}
                <tr>
                    {{#each this}}
                        <td>{{.}}</td>
                    {{/each}}
                </tr>
            {{/each}}
        </table>
    </script>
    
    <div id="cont"></div>