2
\$\begingroup\$

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:

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

JavaScript:

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

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

    $('body').append(temp(obj));
\$\endgroup\$
1
\$\begingroup\$

For one thing, the <tr> is opened but never closed here:

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

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

  1. 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.
  2. 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 < 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 < 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:

<script type="text/template" id="scheme">
    <table>
            <thead>
                <tr>
                    <% _.each(rows[0], function () { %>
                    <th>Scheme</th>
                    <% }) %>
                </tr>
            </thead>
            <tbody>
                <% _.each(rows, function (cols) { %>
                    <tr>
                    <% _.each(cols, function (item) { %>
                        <td>
                            <%= item.schemeCode %>
                        </td>
                    <% }) %>
                    </tr>
                <% }) %>
            </tbody>
        </table>
</script>
\$\endgroup\$
  • \$\begingroup\$ I understood. But the back-end control not with me. any how thanks for your solution. But i not find this is very compact. \$\endgroup\$ – 3gwebtrain Oct 21 '14 at 7:16
  • \$\begingroup\$ I don't see how the backend matters. You could receive 8, 21, 95 data from the backend, it won't make a difference. The original JavaScript can work, by changing only the template, adding another check on index % 7 == 0 for closing the </tr> properly. But it's not good to have the magic number 7 repeated many times, and as I explained, it's better to minimize logic in templates, due to the MVC principle. Compactness should be a secondary concern, and come after correctness and complexity. \$\endgroup\$ – janos Oct 21 '14 at 7:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.