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!
Comments
Man, these posts just rock!
Seriously. I've learned a lot since I discovered this blog.
Thanks on behalf of many .net devs.
Hmm, tried the demo, but it doesn't 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
matt - your posts continue to educate and inspire - keep it up!
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
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
Simply Great any plans to implement style to PagerTemplate too?
Good job matt
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 !!!
Matt, FYI this breaks the AJAX calendar style is you nest one. Trying to get a resolution.
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 don't change until the second time I sort the column. Anyone else ran into this?