Tuesday, June 30, 2009

ASP.NET MVC & jQuery Part 2: Zebra Striping

This is the 2nd blog post in a series taken from a recent presentation I gave at CodeStock. The previous blog posts are available here...

  1. ASP.NET MVC & jQuery Part 1: Adding jQuery Intellisense to VS 2008

Probably one of the coolest things you learn (if you haven’t already) after picking up jQuery is realizing how easy it is to add zebra striping to your tables (alternating row color shading) as demonstrated in the following picture.

FireShot capture #1 - 'Scriptlet' - localhost_8080_Zebra_Scriptlet

Before I knew jQuery I used to write code the like the following in order to get the zebra striping appearance for my tables… which stinks to high heaven!

     <table class="styled">
        <tr>
            <th>Id</th>
            <th>Name</th>
            <th>Description</th>
            <th>Price</th>
        </tr>

    <% for (var i = 0; i < Model.Count(); ++i ) {
        var item = Model.ElementAt(i);    
    %>
    <% if (i % 2 == 0) { %>
        <tr>
    <% } else { %>
        <tr class="alt">
    <% } %>
            <td>
                <%= Html.Encode(item.Id)%>
            </td>
            <td>
                <%= Html.Encode(item.Name)%>
            </td>
            <td>
                <%= Html.Encode(item.Description)%>
            </td>
            <td>
                <%= Html.Encode(String.Format("{0:F}", item.Price))%>
            </td>
        </tr>
    <% } %>
    </table>
 

Obviously, we want to keep our Views in MVC as simple as possible and even though modular logic isn’t overly complicated, we still should keep it out of the View if at all possible.

It would be optimal to keep out the modular logic and keep the View simple like the following…

      <table class="styled">
        <tr>
            <th>Id</th>
            <th>Name</th>
            <th>Description</th>
            <th>Price</th>
        </tr>

    <% foreach (var item in Model) { %>
        <tr>
            <td>
                <%= Html.Encode(item.Id) %>
            </td>
            <td>
                <%= Html.Encode(item.Name) %>
            </td>
            <td>
                <%= Html.Encode(item.Description) %>
            </td>
            <td>
                <%= Html.Encode(String.Format("{0:F}", item.Price)) %>
            </td>
        </tr>
    <% } %>
    </table>
 

This is where jQuery comes in handy! With the following line of code we can add zebra striping…

<script type="text/javascript">
    $(document).ready(function() {
        $(".styled tr:even").addClass("alt");  
    });
</script>

That was easy :) The jQuery line selects all the even rows from the table with the “styled” class attribute and adds the “alt” to all the class attributes which provides the alternating row shading.

Another common usability feature that users tend to like is row hover highlighting. Well, this turns out to be another easy thing to do with jQuery. The following code selects all the rows in the table with the “styled” class and attaches a mouseover and mouseout event to all of them. When those events get fired jQuery will either add or remove the “over” CSS definition to/from the class attribute.

<script type="text/javascript">
    $(document).ready(function() {
        $(".styled tr").bind("mouseover mouseout", function() {
            $(this).toggleClass("over");
        });
    });
</script>

So, after all is said and done our basic table looks like the following with two jQuery function calls :)

Id Name Description Price
1 Ralph Fits A lonely ragged pup that licks himself and isn't house trained 12.99
2 Fluffy Florentine A sweet little kitten that is ready to have a home 277.00
3 Bubba Gump A very stupid dog that can't even find his way to his dog house 999.99
4 Charlie Strango This weird looking puppy scares most adults, but has a strange interest to children 23.44
5 Blacky the Beautiful This beautiful cat is as kind as can be. Who says that a dog is man's best friend? 45.65
6 Snot Nose Nelly If you want to get wet, then this is the pet for you. Talk about snot everywhere! 44.78
7 Darcy Scoop A wonderful black lab with human-like intelligence; however, it does poop a lot. 234.55
8 Supsrirooantsum A very rare cat straight from it's homeland of India. 432.67
9 Clark Kent A self-employed kitten making and selling fur balls for all to enjoy. 44.66
10 Red Headed Bull This dog is unlike any other that you have seen. You can even braid it's flowing red hair. 78.99
11 Rex the Terrible A half german shepard / half wolf aggresive dog that will tear the flesh out of anyone you wish. 346.99
12 Skittish Steve You will never see this dog once you buy it. It'll be like you never had a pet to begin with. 33.00
13 Dart Mouth A dart gun was surgically grafted into this dog's mouth. He is great for parties. 55.00
14 Alien Abbott You never hear this dog bark because it only barks in the future. 777.99
15 Crazy Calico If you like cats, don't get this one because it's pure crazy on a stick! 2.99

3 comments:

  1. I am going to have to strongly disagree with this article.

    The original way that you were handling the styling of the tables - before you learnt jQuery - was much superior for both the user experience and from the point of view of code simplicity and maintenance.

    It is generally best practise for front end development that:

    > HTML handles the structure and content of the document,

    > CSS handles the presentation,

    > and Javascript handles adding behaviours.

    What we are dealing with here is the presentation of a table, therefore we should only be reaching for Javascript as a last resort. As long as the structure of the document is correct then this effect can be completely achieved using simple CSS.

    There no need to use Javascript let alone jQuery. The disadvantages of a javascript solution are:

    > Increased page weight.

    > Slower page rendering. - the styles will not be displayed until the JS has downloaded and been processed. (This could be very significant to mobile users)
    > More complicated code - if the classes are not it the source code it may require knowledge of the JS functions to write the CSS. And the JS function itself is much more complicated than a simple if() statement in the .aspx file.

    So what are the advantages of this method? It seems that the advantages are slightly cleaner .aspx file. In my view this isn't worth the trade.

    I think it would be helpful to see the view as the combination of the .aspx files, the CSS and the Javascript. This way when you consider "want[ing] to keep our Views in MVC as simple as possible" you'll be considering the system as a whole and won't be tempted by false economies in one technology at the expense of the others.

    It's worth noting that all modern browsers except IE6 will allow your to add a hover psuedo class to tr elements. This removes the need for adding the events to each row of the table. Adding these events to a large table would be very likely to cause significant delays in the page display. If you need the hover effect for IE Javascript is the only option, but it would be much more efficient to use event delegation - I would recommend simply not providing this effect for IE6 users though.

    ReplyDelete
  2. "Wow, I hadn't thought about it that way before. Good write up,
    >> very clearly written. Have you written previously about "Zebra Striping"? I'd
    >> love to read more."

    ReplyDelete
  3. That can be done with CSS selectors without having to use Javascript. Most recent versions of all major browsers implement this feature.

    ReplyDelete