Categories
css html javascript knockout.js twitter-bootstrap

Bootstrap CSS table-striped not working with knockout if binding

Let’s say I have the following table that works with bootstrap css and knockout:

<table  style="cursor:pointer;" class="table table-striped table-bordered table-hover table-condensed">
<tbody data-bind="foreach: items">
<tr>
<td data-bind="text: name"></td>
</tr>
<tr data-bind="if: somecondition">
<td>test</td>
</tr>
</tbody>
</table>

Now if I set "somecondition" to return "true", I can see the result table has the zebra striping. Everything is fine. But if I change the condition to “false”, obviously the row disappears from the screen, but I don’t see any alternating row color at all. Anybody knows why and how I can make the alternating row color shown?

The problem is that the Knockout if binding doesn’t control whether the element it’s on will exist or not, just whether that element’s content will exist or not. (This isn’t as clear from the documentation as it might be, but it is there, mostly in the “Note: Using “if” without a container element” bit). So the if in your example will control whether the content of the tr is present, but the tr will be there regardless, giving you a tr with absolutely nothing in it, which counts as part of the :nth-child work that the Bootstrap striping does but not occupying any vertical space. (You can see this by rendering the page, then right-clicking the table and using “Inspect element” in any modern browser to look at what’s actually in the DOM.)

To make the entire row exist/not exist based on the condition, wrap the row with a KO virtual element:

<!-- ko: if: somecondition -->
<tr>
<td>test</td>
</tr>
<!-- /ko -->

Example of your original code, not striping correctly: http://jsbin.com/tupusemu/1

Example using a virtual element, striping correctly: http://jsbin.com/tupusemu/2