Alternating styles in DataView

A few months ago, I showed how you can alternate styles using CSS in a server-side ListView, by selecting the class depending on the remainder of the division of the data index by two.

Well, you can do the exact same thing with the client-side DataView.

Let’s first define the classes we’ll want to apply to the even and odd rows:

tbody tr {
    background-color: #f0f0f0;
}
tbody tr.odd {
    background-color: #c0c0c0;
}

Then, we can use the class namespace to bind the presence of a CSS class to a Boolean condition:

<tr class:odd="{{ $index % 2 }}">

Within the context of the template, $index is the index of the current data item, so $index % 2 will be evaluated as 1 and 0 alternatively. For JavaScript, when evaluated in a Boolean context, these are equivalent to true and false, so the class “odd” will be alternatively present and absent from the rows.

Here’s the complete template:

<table>
    <thead><tr><td>Name</td><td>Age</td></tr></thead>
    <tbody id="peopleIKnow"
sys:attach="dataview" class="sys-template"> <tr class:odd="{{ $index % 2 }}"> <td>{{ name }}</td> <td>{{ age }}</td> </tr> </tbody> </table>

And here’s what the rendering looks like:

AltStyles

The full source code for the page can be found here and uses Microsoft Ajax 4.0 Preview 3:

http://weblogs.asp.net/blogs/bleroy/Samples/TemplateAlternating.htm.txt

11 Comments

  • That's horrible non-semantic code. You shouldn't be touching anything to do with styling at this point in the data flow. These sort of problems have already been solved - Simply use the tr:nth-child(even) CSS selector.

    or if you happen to use a web browser without that support, you can map it in a runtime easily with JQuery:

    $('#peopleIKnow tr:nth-child(even)').addClass('even');

  • While I appreciate Microsoft's constant future thinking I'd appreciate it if you please indicate in an article title when the solution or its code requires beta, release-candidate or other non-release technology. This rule should be applied to all articles, solutions and code on this site. Keep up the great work in keeping us informed.

  • With Microsoft adopting jQuery would it not be easier to use the :odd filter to style the rows?

  • @Rich: you might not want to take an additional 18kB dependency just to add style. You are right that nth-child is unfortunately not supported by all currently common browsers and that otherwise it would work nicely in this case. Except that "class" has the advantage of removing the coupling between the shape of the markup and the style. If you decide to switch from a table to a plain list, for example, your CSS rule would have to be rewritten. Not so if you use a class like I do. But I concede that from a purely semantic standpoint, the stylesheet should be the right place, but maybe you'd want at least to write this rule without relying on tr. You should also see beyond this example that CSS can't do everything. For example, imagine that you want to put a green background behind stock quotes that have a raising value and red on the other ones, or some more complicated business rule. In such cases, the method above is both useful and semantically correct (the rule to apply the class is then no longer positional but is now data-driven, so it belongs in the template).

    @David: I'm not sure what I could have said that would have made it clearer... From the post, "uses Microsoft Ajax 4.0 Preview 3". Also, the DataView control has never been released in anything else than previews.

    @Chris: that's if you are using jQuery, which is an additional and optional 18kB dependancy. We support the use of jQuery but we're not forcing our users to adopt it.

  • @Rich: What if the alternate coloring was a user preference? Then what?

  • I would sacrifise 18kb for the ease jQuery places on html manipulation. I think that the ASP.NET AJAX templates combined with jQuery make desktop applications on the web seem relatively easy. An exciting time to be a web developer.

  • I like it. It removes the ugly concatenation of css classes. I understand and agree in the use of :nth-child or :odd with either css or jquery, but that just applies to this example.

    Thinking of applying a cssClass upon $dataItem state, I would like to see bindings (probably with converters).

    For example, in a TODO list, dom that display item could have a class="completed" binded to a item.Completed property. Otherwise some code is necessary on OnItemCreated to achieve that.

  • i am sure tha Microsoft client templating will be the easiest solution in the market BUT i ask my self why you need to develop a new method of templating and indeed not extend other already build client templating mechanism (e.g. even written in JQuery)?

    I am sure that with the great power of Microsoft people such as you JQuery would become even larger and more adopted.

  • This technique would be useful for assigning a class name to an element when the logic involved is more complicated than "is this row odd or even?"

    Anyways, speaking of bit forcing people to adopt JavaScript libraries, any chance of us being able to get rid of WebResouce.axd scripts or at least being able to put them on a CDN?

  • @Joe: you can get rid of scriptresource.axd by adding script references with the same name but with a path. As for webresource.axd, for the moment, the only way to suppress them is not to use the features that bring them in (such as Menu, TreeView, validation, etc.). For the CDN, that should be available very soon for the Microsoft Ajax files.

  • @bleroy: 18Kb is 10% of the page weight of this blog page. I can live with that.

    @foobar: It depends on where the user preference is stored. DOM storage, then you're doing everything client-side anyway. Server-storage, then you can switch stylesheets/JavaScript shims depending on user.

Comments have been disabled for this content.