A YUI DataTable Styled GridView

Lately I have been spending more and more time browsing through the YUI Developer pages.  I have worked exclusively with Microsoft's .Net Framework for the past 5 years, but I find it interesting to learn about other competing technologies as well (I even went so far to get certified on Sun's Java platform).  I don't know if it is boredom or curiosity, but I generally find it interesting to see what tools, development environments, programming languages and other techniques non-Microsoft engineers are using.  I try to come out of these research projects with something concrete that I can potentially use in my day to day activities as a .Net web developer.

During my most recent effort I came across what I thought was a slick looking GridView like control (YUI calls it a DataTable Control).  You can play around with the interactive demo for it here

The control renders as an HTML Table, and has a few sorting features that are sometimes a little difficult to do with the standard asp:GridView.  The first is how the column header changes it's background image and shows a directional indicator.  The second feature I like is how the cell and alternating cell background colors change to make it obvious which column is currently being sorted.  The YUI DataTable Control also supports resizing of the column headers (I left this out of this example, but you can read about an approach for doing this here).

If you like this style of GridView, you can do the following to incorporate it into your site.

Live Demo (Tested in FF, IE7 and IE6) | Download

Download the Following 3 Images

  

Once you have them downloaded, save them to a folder called img that is a sub-directory of the root of your web application (this is where our CSS style's will be looking for them).  The two shaded boxes are contained in a single image sprite and is used for the background for the header cells.  The next two triage images are used for the sort direction indicators.

Add the GridView to Your Page

Next you can go ahead and add the GridView to your page.  Because we are controlling the styling via CSS, you will need to set the GridView's CssClass attribute to tablestyle, the AlternatingRowStyle CssClass attribute to altrowstyle, the HeaderStyle CssClass attribute to headerstyle and finally the RowStyle's CssClass attribute to rowstyle.  Also, make sure to handle the GridView's RowDataBound event, this is where we will be setting additional style classes for cells that are involved in the sort.

<asp:GridView 
    ID="gvCustomers" runat="server" CssClass="tablestyle" 
    AllowSorting="true" DataSourceID="odsCustomers" 
    OnRowDataBound="GvCustomers_RowDataBound" AutoGenerateColumns="false">
    <AlternatingRowStyle CssClass="altrowstyle" />
    <HeaderStyle CssClass="headerstyle" />
    <RowStyle CssClass="rowstyle" />
    <Columns>
        <asp:BoundField HeaderText="ID" DataField="customerid" SortExpression="customerid" />
        <asp:BoundField HeaderText="Company" DataField="companyname" SortExpression="companyname" />
        <asp:BoundField HeaderText="Contact Name" DataField="contactname" SortExpression="contactname" />
        <asp:BoundField HeaderText="Contact Title" DataField="contacttitle" SortExpression="contacttitle" />
        <asp:BoundField HeaderText="Country" DataField="country" SortExpression="country" />
        <asp:BoundField HeaderText="Phone" DataField="phone" SortExpression="phone" />
    </Columns>
</asp:GridView>

Handle the GridView's RowDataBound Event

In this method I have a little chunk of code that first determines the index of the cell that is currently being sorted.  Once it obtains this index, I set the CssClass property to either sortascheader or sortdescheader for the header row cell, or sortaltrow and sortrow for the data row cells. 

protected void GvCustomers_RowDataBound(object sender, GridViewRowEventArgs e)
{
    GridView gridView = (GridView)sender;

    if (gridView.SortExpression.Length > 0)
    {
        int cellIndex = -1;
        //  find the column index for the sorresponding sort expression
        foreach (DataControlField field in gridView.Columns)
        {
            if (field.SortExpression == gridView.SortExpression)
            {
                cellIndex = gridView.Columns.IndexOf(field);
                break;
            }
        }

        if (cellIndex > -1)
        {
            if (e.Row.RowType == DataControlRowType.Header)
            {
                //  this is a header row,
                //  set the sort style
                e.Row.Cells[cellIndex].CssClass +=
                    (gridView.SortDirection == SortDirection.Ascending
                    ? " sortascheader" : " sortdescheader");  
            }
            else if (e.Row.RowType == DataControlRowType.DataRow)
            {
                //  this is a data row
                e.Row.Cells[cellIndex].CssClass +=
                    (e.Row.RowIndex % 2 == 0
                    ? " sortaltrow" : "sortrow");
            }
        }
    }            
}

Include the Following Stylesheet in Your Page

Finally, after the code that adds in our style classes has been added, we can go ahead and link a stylesheet to the page that contains the following style rules ...

.tablestyle 
{
    font-family: arial;
    font-size: small;
    border: solid 1px #7f7f7f;
}

.altrowstyle 
{
    background-color: #edf5ff;
}

.headerstyle th 
{
    background: url(img/sprite.png) repeat-x 0px 0px;
    border-color: #989898 #cbcbcb #989898 #989898;
    border-style: solid solid solid none;
    border-width: 1px 1px 1px medium;
    color: #000;
    padding: 4px 5px 4px 10px;
    text-align: center;
    vertical-align: bottom;
}  

.headerstyle th a
{
    font-weight: normal;
    text-decoration: none;
    text-align: center;
    color: #000;
    display: block;
    padding-right: 10px;
}    

.rowstyle .sortaltrow, .altrowstyle .sortaltrow 
{
    background-color: #edf5ff;
}

.rowstyle .sortrow, .altrowstyle .sortrow 
{
    background-color: #dbeaff;
}

.rowstyle td, .altrowstyle td 
{
    padding: 4px 10px 4px 10px;
    border-right: solid 1px #cbcbcb;
}

.headerstyle .sortascheader 
{
    background: url(img/sprite.png) repeat-x 0px -100px;
}

.headerstyle .sortascheader a 
{
    background: url(img/dt-arrow-up.png) no-repeat right 50%;
} 

.headerstyle .sortdescheader 
{
    background: url(img/sprite.png) repeat-x 0px -100px;
}   

.headerstyle .sortdescheader a 
{
    background: url(img/dt-arrow-dn.png) no-repeat right 50%;
} 

That's it.  Enjoy!


TrackBack

TrackBack URL for this entry:
http://mattberseth.com/blog-mt/mt-tb.fcgi/74

Listed below are links to weblogs that reference A YUI DataTable Styled GridView:

» Your grid needs 20 pieces of flare. from Coding4Fun
Every one knows (most) developers can't design. If it was left up to us, everything would be command [Read More]

» YUI for ASP.NET from Software Engineering: From Flash to .NET & Beyond
I've recently started playing around with the Yahoo! User Interface Library (hey, maybe I'm a little behind the times), and all I can say is WOW - this is some great stuff. I love the grid based css generator, the... [Read More]

Comments


Posted by: Robert on October 7, 2007 12:00 AM

Man, these posts just rock!

Seriously. Ive learned a lot since I discovered this blog.

Thanks on behalf of many .net devs.

Posted by: sirrocco on October 8, 2007 12:00 AM

Hmm, tried the demo, but it doesnt work for me : FF 2.0.0.7. I just click and click and nothing happens, eventually I pressed F5 and got a : "unable to parse date " or something like that.

I guess an EnableEventValidatation="false" might do the trick.

@sirrocco -

Thanks for the feedback. Would you mind retesting it again with FF 2.0.0.7? I just tried it with my local copy and was not able to reproduce the problem.

Thanks,
Matt

Posted by: grant on October 9, 2007 12:00 AM

matt - your posts continue to educate and inspire - keep it up!

Posted by: Sean on October 9, 2007 12:00 AM

I converted it to VB and tested it with FF 2.0.0.7, IE7, IE6 and Opera 9.22. Works great in all of them.

Thanks and I look forward to more!

@grant -

Those are very kind words. Thanks.

Matt.

@Sean -

Awesome. I was hoping someone else would verify that for me!

Thanks,
Matt

Posted by: frank on October 10, 2007 12:00 AM

Very good, but if you want a good grid go to http://extjs.com/ in left menu click on Grids and Trees y watch the demo.

regards
Frank

Posted by: Naveen on November 26, 2007 12:00 AM

Simply Great any plans to implement style to PagerTemplate too?

Posted by: Mus on November 26, 2007 12:00 AM

Good job matt

Posted by: vish on December 20, 2007 12:00 AM

Hi Matt,
I was seeing and creating CSS on my own,

I think,
there is no need to write
.rowstyle .sortaltrow, .altrowstyle .sortaltrow

and

.rowstyle .sortrow, .altrowstyle .sortrow


instead just write

.rowstyle .sortrow
{
background-color: #edf5ff;
}

.altrowstyle .sortrow
{
background-color: #dbeaff;
}

and change

else if (e.Row.RowType == DataControlRowType.DataRow)
{
// this is a data row
e.Row.Cells[cellIndex].CssClass += "sortrow";
}

It works for me...
Hope it works for you also !!!

Posted by: Tim on March 3, 2008 12:00 AM

Matt, FYI this breaks the AJAX calendar style is you nest one. Trying to get a resolution.

Posted by: icastel on April 28, 2008 12:00 AM

This works great. Thank you Matt. I only have one issue: when I use the "Sorting" event to change the default sort for a column, the sort indicator or the column style dont change until the second time I sort the column. Anyone else ran into this?

Posted by: Johnson on August 8, 2008 02:46 AM

Your post is very helpful! Keep it up!

Post a comment

(If you haven't left a comment here before, you may need to be approved by the site owner before your comment will appear. Until then, it won't appear on the entry. Thanks for waiting.)

Consulting Services

Yep - I also offer consulting services. And heck, I'll do just about anything. If you enjoy my blog just drop me an email describing the work you need done.

Recent Comments

  • Johnson wrote: Your post is very helpful! Keep it up!...
  • icastel wrote: This works great. Thank you Matt. I only have one issue: when I use the "Sorting" event to change ...
  • Tim wrote: Matt, FYI this breaks the AJAX calendar style is you nest one. Trying to get a resolution. ...
  • vish wrote: Hi Matt, I was seeing and creating CSS on my own, I think, there is no need to write .rowstyle .sor...
  • Naveen wrote: Simply Great any plans to implement style to PagerTemplate too? ...
  • Mus wrote: Good job matt ...
  • frank wrote: Very good, but if you want a good grid go to http://extjs...
  • grant wrote: matt - your posts continue to educate and inspire - keep it up! ...