MooTools Zebra Table Plugin
I released my first MooTools class over a year ago. It was a really minimalistic approach to zebra tables and a great first class to write. I took some time to update and improve the class.
The XHTML
<table class="list-table" cellpadding="0" cellspacing="0"> <tr> <th><b>Award</b></th> <th><b>Actor</b></th> <th><b>Film</b></th> </tr> <tr> <td>Actor In A Leading Role</td> <td>Daniel Day-Lewis</td> <td>There Will Be Blood</td> </tr> <tr> <td>Actress In A Leading Role</td> <td>Marion Cotillard</td> <td>La Vie en Rose</td> </tr> <tr> <td>Actor In A Supporting Role</td> <td>Javier Bardem</td> <td>No Country For Old Men</td> </tr> <tr> <td>Actress In A Supporting Role</td> <td>Tilda Swinton</td> <td>Michael Clayton</td> </tr> <tr> <td>Directing</td> <td>Joel Coen and Ethan Coen</td> <td>No Country For Old Men</td> </tr> </table>
You may have as many tables as you want.
The CSS
.highlight { background:#d5fcdc; } .even { background:#fff; } .mo { background:#e3f1fb; } .odd { background:#eee; } .list-table th { padding:5px; background:#ddd; border-bottom:1px solid #999; text-align:left; font-weight:bold; } .list-table td { padding:5px 20px 5px 5px; border-bottom:1px solid #ddd; }
The above are the classes are configurable using the plugin's options.
The MooTools JavaScript
var ZebraTable = new Class({ //implements Implements: [Options,Events], //options options: { elements: 'table.list-table', cssEven: 'even', cssOdd: 'odd', cssHighlight: 'highlight', cssMouseEnter: 'mo' }, //initialization initialize: function(options) { //set options this.setOptions(options); //zebra-ize! $$(this.options.elements).each(function(table) { this.zebraize(table); },this); }, //a method that does whatever you want zebraize: function(table) { //for every row in this table... table.getElements('tr').each(function(tr,i) { //check to see if the row has th's //if so, leave it alone //if not, move on if(tr.getFirst().get('tag') != 'th') { //set the class for this based on odd/even var options = this.options, klass = i % 2 ? options.cssEven : options.cssOdd; //start the events! tr.addClass(klass).addEvents({ //mouseenter mouseenter: function () { if(!tr.hasClass(options.cssHighlight)) tr.addClass(options.cssMouseEnter).removeClass(klass); }, //mouseleave mouseleave: function () { if(!tr.hasClass(options.cssHighlight)) tr.removeClass(options.cssMouseEnter).addClass(klass); }, //click click: function() { //if it is currently not highlighted if(!tr.hasClass(options.cssHighlight)) tr.removeClass(options.cssMouseEnter).addClass(options.cssHighlight); else tr.addClass(options.cssMouseEnter).removeClass(options.cssHighlight); } }); } },this); } }); /* do it! */ window.addEvent('domready', function() { var zebraTables = new ZebraTable(); });
The improvements to this class include:
- General MooTools style consistency
- CSS class flexibility
- Checks to make sure the table heading rows (rows with "th") are untouched
- You may use the zebraize method after class initialization
- Table highlighting has been separated
The class is still very basic. This plugin does not contain sorting functionality nor was it designed to.
Need basic table highlighting? Download it!
Seeing how you can accomplish this with some CSS, PHP + Modulo operator and loop I’m not sure how much sense it makes to rely upon JS to do this task for you.
Unless you’re not exporting items from a database. But if that’s the case, then your tables will most likely be short anyways making it easy to just add the class names yourself to alternating rows.
Cool, and works well but I still ask myself if JS is really the tool to rely on for the job…..
// Tim
click function can be made simpler…
@Jacob: I believe I had that at first but the cssHighlight was causing issues once the item had been clicked off.
@Tim you can’t do this with CSS if it is to work the same in IE 6 & 7 tho can you?
@Jacob: You couldn’t with the hover — IE6 wouldn’t like that. In my opinion, adding special classes/colors in PHP is really ugly, although a tad safer than JS.
nice tutorial! additional information for me! thanks.
Great plugin!, already implemented it.
However, i would like to know how do i do if i want the previous selected row to go back with the previous tag once i click or select another row.
Regards,
Alex!
I think it’s ok in this case, it’s only for aesthetic, so leaving this job to the client side, even though it’s not a huge task for the server, sounds like a good idea.
Omg, you have no idea how much pain in the ass this will save me
Nice work! But, I have a question. Is this posible to make something like this for definitions lists?
@Hiway: Yep, you’ll just need to modify the class to look for the proper XHTML tags.
@David Walsh: Thanks, David! That’s OK. But, in your JS code you are working basically only with <tr>-element, and almost the whole formating applying to this element. In that time, when in the list of definitions we don’t have general element for <dt> & <dd> exept <dl>, but one list of definitions can have many <dt> & <dd>, and exactly for these ones we need to apply a “Zebra” formating.
@david: Why aren’t you just using CSS3 nth-child selectors (http://tinyurl.com/czhlp2)? MooTools support CSS3, and zebra striping is quite easy with CSS3-selectors.
I’ve made a rough example with mootools here: http://ljd.dk/loot/mootables.html. I’ve only tested in FF3, IE8 and IE8 compatability view, but so far it seems to works just like yours with less code.
Maybe I’m misunderstanding something, but imho it wouldbe easier to use CSS3 selectors. Thanks for a great blog!
This is way easier with jQuery if you want to follow the JavaScript route.
eg:
$("myTable tr:odd).css("background-color", "#000");
would colour the odd rows.@Phil: Writing that in Moo would be just as short — my class does much more than simple color every odd row differently.
Nice!
I would use <thead> for the headers and <tbody> for the data rows, and that way save the <th> check.
Hmm it would be very cool if the zebratable are dynamically. A function for addRow or something like this :)
I tried to make but without success :/
I’ve been modifying this plugin somewhat for a project I am working on, and I’ve encountered some problems with it.
The project I am working on involves hierarchical data in a table, arranged as a series of ‘entry’ rows and ‘folder’ rows. Clicking on a folder row hides or shows the corresponding hierarchy of entries or subfolders. This was easy enough, but I wanted to use this class to recolour the table rows dynamically (as hiding a bunch of rows may throw off the zebra effect).
Modifying the code so that it checked for
tr.style.display != 'none'
was trivial, as was adding the extra voodoo to make the zebra effect work independently of row number, but then I found the code did not work reliably after more than one call.The problem was actually something I should have noticed from the start:
zerbarize()
doestr.addClass(klass).addEvents( ... );
*but it doesn’t remove the style classes or events before doing so*, so each call tozebraisze()
is just adding classes and event handlers rather than replacing the existing ones!In the end, I used the following code:
I can link you to a pastebin of the complete modified version if you’re interested.
“Seeing how you can accomplish this with some CSS, PHP + Modulo operator and loop I’m not sure how much sense it makes to rely upon JS to do this task for you.”
Outputting the stripes server-side, you’d need to add that bit of logic to every table you output. It’s not much code, about 5 rows, but it’s duplication nonetheless and requires testing each table separately. Using JS to modify all tables of say, given class or id, you’d have the logic in just one place, with the benefits of centralized control.
Of course, if you happen to have a method of generating the tables through a single routine in the server-side code, you’d then only have to code the striping once, but a lot of us don’t probably have that luxury always, especially with legacy apps.
Using PHP would obviously work without JS, so it all depends on can you trust the user to have JS on.