views:

112

answers:

3

What I know: Rails has the cycle() method that enables odd/even rows in a table to have different CSS classes. We can pass multiple classes to the cycle() method and that works great.

I wanted rows which are grouped in three's; so, I used this:

...some html-table  code...
<tr class="<%= cycle("table_row_1","table_row_2","table_row_3","table_row_4","table_row_5","table_row_6") %>">
...some more html-table  code...

The corresponding CSS I defined is:

.table_row_1 { background-color: red;}
.table_row_2 { background-color: red;}
.table_row_3 { background-color: red;}
.table_row_4 { background-color: blue;}
.table_row_5 { background-color: blue;}
.table_row_6 { background-color: blue;}

It works, but it doesn't feel "clean".

Is there a recommended way to do this in Rails ?

UPDATES

  1. On similar lines to @Ryan Bigg's answer, is it possible to generate strings in sequence so that the cycle() method can be sent strings of the form prefix_1 prefix_2 prefix_3 somehow using the *3 syntax or some other way?
  2. The inspiration to use this "every third row" striping came from an article on Edward Tufte's site
  3. It seems CSS3 can do this (link), but that's not widely supported at this time :(
  4. Not related to question, but I just searched for this problem I have on Google, and the questions listed at questionhub.com! I never asked this on questionhub.com!
  5. Now its on http://loopingrecursion.com too! What's going on.
+2  A: 

How about this?

<tr class="<%= cycle(*[["striped"]*3,["unstriped"]*3].flatten) %>">
Ryan Bigg
After adding a space after the "striped", it still doesn't work -- I get for row 1: `<tr class="striped striped striped ">` and row 2:`<tr class="unstriped unstriped unstriped ">` and the process repeats, thus getting the even/odd effect.
Zabba
@Zabba: Updated answer to use splat operator and flatten. This will work now.
Ryan Bigg
This works! Thanks!
Zabba
+1  A: 

Actually this sounds like something i would solve using pure CSS:

table tr:nth-child(6n+1), table tr:nth-child(6n+2), table tr:nth-child(6n+3) { background:red;} 
table tr:nth-child(6n+4), table tr:nth-child(6n+5), table tr:nth-child(6n)   { background:blue;} 

While this is short and dandy, this does not work in IE unfortunately (it will work in the new IE9).

To get this working you could use jQuery, which offers the same selectors and is completely cross-browser compatible.

In your css you add two classes:

table_row_third_even { background: red;}
table_row_third_odd { background: blue;}

and then you write some javascript (inside application.js for instance), like this

$(function() {
  $('table tr:nth-child(6n+1), table tr:nth-child(6n+2), table tr:nth-child(6n+3)').addClass('table_row_third_even');
  $('table tr:nth-child(6n+4), table tr:nth-child(6n+5), table tr:nth-child(6n)').addClass('table_row_third_odd');
});

and your table would have to have the class highlight (you should change that to a better suiting name, this is just an example); but nothing specific for your tr tags, as they will be added by the javascript code.

<table class='highlight'>
  <tr> ... </tr>
  <tr> ... </tr>
  <tr> ... </tr>
  <tr> ... </tr>
</table>

But for this to work you would need to introduce jQuery inside your project. The good thing: it would keep your ruby-code clear from the clutter needed to do this.

Hope this helps!

nathanvda
Good to note that there is no IE support for this. Not even IE 8.
Russell Dias
Really? Bummmmmmmer. One could always consider jquery to the rescue :)
nathanvda
A: 

I found a way to do this, which is sort of "clean" and suits me for now. Details:

In a controller helper (no error checking, yet!):

def cycle_every_third(options = [])
  cycle(options[0],options[0],options[0],options[1],options[1],options[1])
end

HTML:

...
<tr class="<%= cycle_every_third(["table_row_1","table_row_2"] ) %>">
...

CSS:

.table_row_1 {   background-color: red;}
.table_row_2 {   background-color: blue;}

Is that a good way to go about this I wonder? Any pitfalls in Rails I may not be aware of, of calling cycle() inside a helper method as opposed to calling it in the rhtml/erb file?

Zabba
This would definitely work, and no real arguments against it. I would prefer to use the suggestion from @Ryan_Bigg, as i find that more compact and clearer (i find `*3` easier to understand than a row of items ... but i guess that is subjective).
nathanvda