views:

448

answers:

4

Doing odd/even styling with jQuery is pretty easy:

$(function() {
  $(".oddeven tbody tr:odd").addClass("odd");
  $(".oddeven tbody tr:even").addClass("even");
});

Now I came across an interesitng problem today. What if you want to style alternating groups of elements? For example, alternating blocks of 3. Longhand this can be done this way:

$(function() {
  $(".oddeven3 tbody tr:nth-child(3n+1)").addClass("odd");
  $(".oddeven3 tbody tr:nth-child(3n+2)").addClass("odd");
  $(".oddeven3 tbody tr:nth-child(3n+3)").addClass("odd");
  $(".oddeven3 tbody tr:nth-child(3n+4)").addClass("even");
  $(".oddeven3 tbody tr:nth-child(3n+5)").addClass("even");
  $(".oddeven3 tbody tr:nth-child(3n+6)").addClass("even");
});

Seems a bit longwinded though. Now it can be somewhat simplified and made generic like this:

function oddEvenGroupStyle(groupSize) {
  for (var i=1; i<=groupSize; i++) {
    $(".oddeven" + groupSize + " tbody tr:nth-child(" + groupSize + "n+" + i + ")").addClass("odd");
    $(".oddeven" + groupSize + " tbody tr:nth-child(" + groupSize + "n+" + (groupSize+i) " + ")").addClass("even");
  }
}

and:

$(function() {
  oddEvenGroupStyle(3);
});

Seems like a bit of a hack to me though. Is there some more jQuery-ish way of selecting the right rows?

+2  A: 
function oddEvenGroupStyle(groupSize) {
    var even = false;
    $('tr').each( 
        function(i){ 
            if(!(i % groupSize)) even = !even;
            $(this).attr('class', (even ? 'groupEven':'groupOdd') ); 
    })
}
pawel
5th line. I might be wrong but I guess it won't work.
ohnoes
I've tested it in Firefox, IE and Opera, using groupSize in range 1 to 11, everything woked well :)
pawel
Why wouldn't you use addClass instead of attr()?
cletus
cletus
+2  A: 

cletus, if you'd like to get the job done 101% jQuery-ish consider:

  1. using each instead of classic for loop
  2. extending jQuery selector behaviour? (just a hint)
ohnoes
+1 Interesting idea. The above solution was a quicker path for this problem but I'll definitely look into this a bit later. I like the idea of it.
cletus
A: 

I would add a class to the first TR in a group:

<tr class="group"><td>Group 1</td></tr>
<tr class="grouppart"><td>Part of group 1</td></tr>
<tr class="grouppart"><td>Part of group 1</td></tr>
<tr class="group"><td>Group 2</td></tr>
...

This way you can change the size of groups as you go without any modification to your javascript.

// Format the groups:
$("tr.group:even").addClass("even");
$("tr.group:odd").addClass("odd");

// Then apply to groupparts:
$("tr.grouppart").each(function(){
    var oGroup = $(this).prevAll("tr.group:first");
    if(oGroup.hasClass("even")){$(this).addClass("even");}
    if(oGroup.hasClass("odd")){$(this).addClass("odd");}
});

Note: I wrote this from memory, so there might be some small glitches in there. Please comment if that's the case and I'll fix it.

svinto
This is for largely static content so I just want to control the styling with minimal CSS, preferably just by adding a class to the table.
cletus
A: 

1) why have a odd AND and a even class, if you have a default style and then have a overriding odd it will probably be quicker

2) can't you render out the html with the styling already applied? say if your doing this in PHP or ASP.net. doing it after the fact is slower, especially if you have a lot of rows.

BPAndrew
As it happens I do have just an odd class but Ifigured I'd ask in the more general case when you wanted both.
cletus