Learning jQuery - Alternating Triplets
Suppose we want to use two colors, but have each one display three rows at a time. For this, we can employ the odd and even classes again, as well as the modulus operator. But we'll also reset the class each time we're presented with a row containing <th> elements.
If we don't reset the alternating row class, we may be faced with unexpected colors after the first group of rows is striped. So far, our example table has avoided such problems because the first group consists of 12 rows, which, conveniently, is divisible by both 2 and 3. For the triplet striping scenario, we'll remove two rows, leaving us with 10 in the first group, to emphasize the class resetting.
We begin this striping technique by setting two variables, rowClass and rowIndex. We'll use the .each() method this time as well, but rather than relying on the built-in index, we'll use a custom rowIndex variable so that we can reset it on the rows with <th>:
$(document).ready(function() { var rowClass = 'even'; var rowIndex = 0; $ ('table.striped tbody tr'). each(function(index ) { $(this).addClass(rowClass); }); });
%24%28document%29.ready%28function%28%29%20%7B%20%0A%0D%0Avar%20rowClass%20%3D%20%27even%27%3B%20%0A%0D%0Avar%20rowIndex%20%3D%200%3B%20%0A%0D%0A%24%28%27table.striped%20tbody%20tr%27%29.each%28function%28index%29%20%7B%20%0A%0D%0A%24%28this%29.addClass%28rowClass%29%3B%20%0A%0D%0A%7D%29%3B%20%0A%0D%0A%7D%29%3B
Notice that since we have removed the :not([th]) selector, we'll have to account for those subheading rows within the .each(). But first, let's get the triplet alternation working properly. So far, every <tr> will become <tr class="even">. For each row, we can check to see if the rowIndex % 3 equals 0. If it does, we toggle the value of rowClass. Then we increment the value of rowIndex:
$(document).ready(function() { var rowClass = 'even'; var rowIndex = 0; $ ('table.striped tbody tr'). each(function(index ) { if (rowIndex % 3 == 0) { rowClass = (rowClass == 'even' ? 'odd' : 'even'); }; $(this).addClass(rowClass); rowIndex++; }); });
%24%28document%29.ready%28function%28%29%20%7B%20%0A%0D%0Avar%20rowClass%20%3D%20%27even%27%3B%20%0A%0D%0Avar%20rowIndex%20%3D%200%3B%20%0A%0D%0A%24%28%27table.striped%20tbody%20tr%27%29.each%28function%28index%29%20%7B%20%0A%0D%0Aif%20%28rowIndex%20%25%203%20%3D%3D%200%29%20%7B%20%0A%0D%0ArowClass%20%3D%20%28rowClass%20%3D%3D%20%27even%27%20%3F%20%27odd%27%20%3A%20%27even%27%29%3B%20%0A%0D%0A%7D%3B%20%0A%0D%0A%24%28this%29.addClass%28rowClass%29%3B%20%0A%0D%0ArowIndex%2B%2B%3B%20%0A%0D%0A%7D%29%3B%20%0A%0D%0A%7D%29%3B
A ternary, or conditional, operator is used to set the changed value of rowClass because of its succinctness. That single line could be rewritten as:
if (rowClass == 'even') { rowClass = 'odd'; } else { rowClass = 'even'; }
if%20%28rowClass%20%3D%3D%20%27even%27%29%20%7B%20%0A%0D%0ArowClass%20%3D%20%27odd%27%3B%20%0A%0D%0A%7D%20else%20%7B%20%0A%0D%0ArowClass%20%3D%20%27even%27%3B%20%0A%0D%0A%7D
In either case, the code now produces table striping that looks like this:

Perhaps surprisingly, the subheading rows have retained their proper formatting. But let's not be fooled by appearances. The 2007 subheading row is now set in the HTML as <tr class="odd"> and the 2006 row has <tr class="even">. In the stylesheet, however, the greater specificity of the element's rule outweighs that of the two classes:
#content tbody th { background-color: #6f93ce; padding-left: 6px; } tr.even { background-color: #eee; } tr.odd { background-color: #ddd; }
%23content%20tbody%20th%20%7B%20%0A%0D%0Abackground-color%3A%20%236f93ce%3B%20%0A%0D%0Apadding-left%3A%206px%3B%20%0A%0D%0A%7D%20%0A%0D%0Atr.even%20%7B%20%0A%0D%0Abackground-color%3A%20%23eee%3B%0A%0D%0A%7D%20%0A%0D%0Atr.odd%20%7B%20%0A%0D%0Abackground-color%3A%20%23ddd%3B%20%0A%0D%0A%7D
Nevertheless, because the rowIndex numbering does not account for these subheading rows, we have mis-classed rows from the start; this is evident because the first striping color change occurs after two rows rather than three.
We need to include another condition, checking if the current row contains a <th>. If it does, we'll set the value of rowClass to subhead and set rowIndex to -1:
$(document).ready(function() { var rowClass = 'even'; var rowIndex = 0; $ ('table.striped tbody tr'). each(function(index ) { if ($('th', this).length) { rowClass = 'subhead'; rowIndex = -1; } else if (rowIndex % 3 == 0) { rowClass = (rowClass == 'even' ? 'odd' : 'even'); }; $(this).addClass(rowClass); rowIndex++; }); });
%24%28document%29.ready%28function%28%29%20%7B%20%0A%0D%0Avar%20rowClass%20%3D%20%27even%27%3B%20%0A%0D%0Avar%20rowIndex%20%3D%200%3B%20%0A%0D%0A%24%28%27table.striped%20tbody%20tr%27%29.each%28function%28index%29%20%7B%20%0A%0D%0Aif%20%28%24%28%27th%27%2C%20this%29.length%29%20%7B%20%0A%0D%0ArowClass%20%3D%20%27subhead%27%3B%20%0A%0D%0ArowIndex%20%3D%20-1%3B%20%0A%0D%0A%7D%20else%20if%20%28rowIndex%20%25%203%20%3D%3D%200%29%20%7B%20%0A%0D%0ArowClass%20%3D%20%28rowClass%20%3D%3D%20%27even%27%20%3F%20%27odd%27%20%3A%20%27even%27%29%3B%20%0A%0D%0A%7D%3B%20%0A%0D%0A%24%28this%29.addClass%28rowClass%29%3B%20%0A%0D%0ArowIndex%2B%2B%3B%20%0A%0D%0A%7D%29%3B%20%0A%0D%0A%7D%29%3B
With rowIndex at -1 for the subheading rows, the variable will be incremented to 0 for the next row—precisely where we want it to start for each group of striped rows. Now we can see the striping with each year's articles beginning with three light colored rows and alternating three at a time between lighter and darker:

A final note about this striping code—while the ternary operator is indeed concise, it can get confusing when the conditions get more complex. The sophisticated striping variations can be more easily managed by using basic if-else conditions instead:
$(document).ready(function() { var rowIndex = 0; $ ('tbody tr'). each(function(index ) { if ($('th',this).length) { $(this).addClass('subhead'); rowIndex = -1; } else { if (rowIndex % 6 < 3) { $(this).addClass('even'); } else { $(this).addClass('odd'); } }; rowIndex++; }); });
%24%28document%29.ready%28function%28%29%20%7B%20%0A%0D%0Avar%20rowIndex%20%3D%200%3B%20%0A%0D%0A%24%28%27tbody%20tr%27%29.each%28function%28index%29%20%7B%20%0A%0D%0Aif%20%28%24%28%27th%27%2Cthis%29.length%29%20%7B%20%0A%0D%0A%24%28this%29.addClass%28%27subhead%27%29%3B%20%0A%0D%0ArowIndex%20%3D%20-1%3B%20%0A%0D%0A%7D%20else%20%7B%20%0A%0D%0Aif%20%28rowIndex%20%25%206%20%3C%203%29%20%7B%20%0A%0D%0A%24%28this%29.addClass%28%27even%27%29%3B%20%0A%0D%0A%7D%20%0A%0D%0Aelse%20%7B%20%0A%0D%0A%24%28this%29.addClass%28%27odd%27%29%3B%20%0A%0D%0A%7D%20%0A%0D%0A%7D%3B%20%0A%0D%0ArowIndex%2B%2B%3B%20%0A%0D%0A%7D%29%3B%20%0A%0D%0A%7D%29%3B
Now we've achieved the same effect as before, but also made it easier to include additional else if conditions.
Trackback(0)
|