Find odd and even rows using $.inArray() function when using jQuery Templates

In the past period I made series of blogs on ‘jQuery Templates in ASP.NET’ topic.

In one of these blogs dealing with jQuery Templates supported tags, I’ve got a question how to create alternating row background.

When rendering the template, there is no direct access to the item index. One way is if there is an incremental index in the JSON string, we can use it to solve this. If there is not, then one of the ways to do this is by using the jQuery’s $.inArray() function.

- $.inArray(value, array) – similar to JavaScript indexOf()

Here is an complete example how to use this in context of jQuery Templates:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <style type="text/css">
        #myList { cursor:pointer; }
        
        .speakerOdd { background-color:Gray; color:White;}
        .speaker { background-color:#443344; color:White;}
        
        .speaker:hover { background-color:White; color:Black;}
        .speakerOdd:hover { background-color:White; color:Black;}
    </style>
    <title>jQuery ASP.NET</title>
    <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.4.4.min.js" type="text/javascript"></script>
    <script src="http://ajax.aspnetcdn.com/ajax/jquery.templates/beta1/jquery.tmpl.min.js" type="text/javascript"></script>
    <script language="javascript" type="text/javascript">
        var speakers = [
            { Name: "Hajan1" },
            { Name: "Hajan2" },
            { Name: "Hajan3" },
            { Name: "Hajan4" },
            { Name: "Hajan5" }
        ];

        $(function () {
            $("#myTemplate").tmpl(speakers).appendTo("#myList");
        });

        function oddOrEven() {
            return ($.inArray(this.data, speakers) % 2) ? "speaker" : "speakerOdd";
        }
    </script>

    <script id="myTemplate" type="text/x-jquery-tmpl">
        <tr class="${oddOrEven()}">
            <td> ${Name}</td>
        </tr>
    </script>
</head>
<body>
    <table id="myList"></table>
</body>
</html>

So, I have defined stylesheet classes speakerOdd and speaker as well as corresponding :hover styles.

Then, you have speakers JSON string containing five items. And what is most important in our case is the oddOrEven function where $.inArray(value, data) is implemented.

function oddOrEven() {
    return ($.inArray(this.data, speakers) % 2) ? "speaker" : "speakerOdd";
}

Remark: The $.inArray() method is similar to JavaScript's native .indexOf() method in that it returns -1 when it doesn't find a match. If the first element within the array matches value, $.inArray() returns 0.
From http://api.jquery.com/jQuery.inArray/

So, now we can call oddOrEven function from inside our jQuery Template in the following way:

<script id="myTemplate" type="text/x-jquery-tmpl">
    <tr class="${oddOrEven()}">
        <td> ${Name}</td>
    </tr>
</script>

And the result is

I hope you like it.

Regards,
Hajan

3 Comments

  • Very clean approach, thanks for sharing.

    Funny, until now I never realised you could also call functions in a template (like you do with ).

    I believe very few tutorials mention this. I used to limit myself to evaluate just the variables, but this looks very handy.

    Thanks again,
    Peter.

  • @Peter, thank you for your comment.
    You can also take a look at the following blog post I made previously: http://weblogs.asp.net/hajan/archive/2010/12/15/jquery-templates-with-asp-net-mvc.aspx
    There you can find another example where I call function from inside jQuery Template. So, the ${ ...} actually evaluates fields, functions or expressions ;).

  • I like the idea, but the implementation seems to lead to ambiguity.

    I'd kind of like to see something more along the lines of:

    &lt;tr class="${oddOrEvenRowClass()}"&gt;

    function oddOfEvenRowClass(){

    &nbsp; &nbsp;return (isCurrentRowEven()) ? "speaker" : "speakerOdd";

    }

    function isCurrentRowEven.....

    To me this makes the code cleaner, easier to maintain and a little more reusable...

Comments have been disabled for this content.