Making empty cells in Underscore template From the back-end, I am receiving 8 data. The client requires showing that the row per data is 7, so I have 1 data in balance. I have created empty data and made the empty cells, which works fine. But is it a correct approach to using Underscore templates?

Here is the live demo

Template:

&lt;script type="text/template" id="scheme"&gt;
    &lt;table&gt;
            &lt;thead&gt;
                &lt;tr&gt;
                    &lt;th&gt;Scheme&lt;/th&gt;
                    &lt;th&gt;Scheme&lt;/th&gt;
                    &lt;th&gt;Scheme&lt;/th&gt;
                    &lt;th&gt;Scheme&lt;/th&gt;
                    &lt;th&gt;Scheme&lt;/th&gt;
                    &lt;th&gt;Scheme&lt;/th&gt;
                    &lt;th&gt;Scheme&lt;/th&gt;
                &lt;/tr&gt;
            &lt;/thead&gt;
            &lt;tbody&gt;
                &lt;% _.each(schemeCodeDetails, function (item, index) { %&gt;
                    &lt;%= index % 7 == 0 ? '&lt;tr&gt;' : null %&gt;
                            &lt;td&gt;
                                &lt;%= item.schemeCode %&gt;
                            &lt;/td&gt;
                &lt;% }) %&gt;
            &lt;/tbody&gt;
        &lt;/table&gt;
&lt;/script&gt;


JavaScript:

var obj = {
"schemeCodeDetails": [
    { "schemeCode": "AFN"},{"schemeCode": "BBT"},{"schemeCode": "BCH*"},
    {"schemeCode": "BCY*"},{"schemeCode": "BDP"},{"schemeCode": "BDQ"},{"schemeCode": "BDV"}, {"schemeCode": "BDW" } ]
}
for(i=0;i&lt;  obj.schemeCodeDetails.length % 7; i++){
    obj.schemeCodeDetails.push({"schemeCode": ""});
}

    var temp = _.template($('#scheme').html());

    $('body').append(temp(obj));
For one thing, the &lt;tr&gt; is opened but never closed here:


&lt;% _.each(schemeCodeDetails, function (item, index) { %&gt;
    &lt;%= index % 7 == 0 ? '&lt;tr&gt;' : null %&gt;
            &lt;td&gt;
                &lt;%= item.schemeCode %&gt;
            &lt;/td&gt;
&lt;% }) %&gt;



For another, it would be better if the template didn't have knowledge about the number 7 at all, for two reasons:


Right now both the JavaScript and the template share this number. If you change it in one place, you must remember to change in the other too.
The template needs special handling for the empty cells, using % 7. Ideally templates should be kind of dumb, and have as little logic as possible.


I suggest organizing the data into rows in the JavaScript, for example in obj.rows, like this:

var obj = {
    "schemeCodeDetails": [
        {"schemeCode": "AFN"},
        {"schemeCode": "BBT"},
        {"schemeCode": "BCH*"},
        {"schemeCode": "BCY*"},
        {"schemeCode": "BDP"},
        {"schemeCode": "BDQ"},
        {"schemeCode": "BDV"},
        {"schemeCode": "BDW"}
    ],
    "rows": []
};

var maxItemsPerRow = 7;
var i;
for (i = 0; i &lt; obj.schemeCodeDetails.length; i++) {
    if (i % maxItemsPerRow == 0) obj.rows.push([]);
    obj.rows[obj.rows.length - 1].push(obj.schemeCodeDetails[i]);
}

for (var j = i % maxItemsPerRow; j &lt; maxItemsPerRow; j++) {
    obj.rows[obj.rows.length - 1].push({"schemeCode": ""});
}

var template = _.template($('#scheme').html());

$('body').append(template(obj));


Using the new field, you could rewrite the HTML like this:

&lt;script type="text/template" id="scheme"&gt;
    &lt;table&gt;
            &lt;thead&gt;
                &lt;tr&gt;
                    &lt;% _.each(rows[0], function () { %&gt;
                    &lt;th&gt;Scheme&lt;/th&gt;
                    &lt;% }) %&gt;
                &lt;/tr&gt;
            &lt;/thead&gt;
            &lt;tbody&gt;
                &lt;% _.each(rows, function (cols) { %&gt;
                    &lt;tr&gt;
                    &lt;% _.each(cols, function (item) { %&gt;
                        &lt;td&gt;
                            &lt;%= item.schemeCode %&gt;
                        &lt;/td&gt;
                    &lt;% }) %&gt;
                    &lt;/tr&gt;
                &lt;% }) %&gt;
            &lt;/tbody&gt;
        &lt;/table&gt;
&lt;/script&gt;