Asp.NET Tutorials
Home > Asp.Net开发 > Improving the Presentation of an Extra-Wide GridView

Hot archives

Improving the Presentation of an Extra-Wide GridView

the codebase for the web application I am currently working on is pretty new.  We ported our legacy application from .Net 1.1 to .Net 2.0 and in the process we did a complete redesign of our presentation and business logic layers.  However, we did not do the same with our data model.  We upgraded from SQL Server 2000 to 2005, but for the most part we kept the exact same datamodel.  So while from a technology standpoint we have a completely new platform, our data model is about 5 years old.  Over those 5 years most of datamodel changes have been the addition of new columns to existing tables.  As a result, a number of our core tables have become quite wide.  And as the tables in our underlying datamodel get wider over time, so do the grids that present the data.        

Live Demo (FF, IE6, IE7) | Download

so during a recent visit to the Ajax Rain site, I came across a sample that had a few features that I thought would be nice to add to our extra-wide grids.

1. Provide row and column mouseover state

2. Provide row and column selected states

 

if you like the demo and are curious how you can add it to your existing site, you can visit the Tablecloth home page and download the code for it.  The JavaScript source is well written and very easy to understand.  Because there is a good chance we will be incorporating a similar approach into our web application, I refactored the Tablecloth example to use the ASP.NET AJAX client side API.  If we do decide to take this approach, I know there are other client-side GridView extension features we would like to roll into a single extender.  This is probably the starting point for this work ...     

<mb:GridViewExtender 
    runat="server" TargetControlID="gvCustomers"
    MouseOverCssClass="over" MouseDownCssClass="down" SelectedCssClass="selected" 
/>

Define the CSS Classes

for this sample. the following 3 CSS classes are used: .over, .selected, .down.  When the mouse is hovered over a cell, the .over class is applied to all of cells in the current cell's row and column.  When the users clicks in a cell to select it, the .selected class is applied to all of the cells in the row/column and finally, when the cells mousedown event fires, the .down class is applied to these cells as well.

for this sample, here are all the stylesheet rules that I used ...

/* table style */
table
{
    font-family:Arial,Helvetica,sans-serif;
    color:#555555;
    border-collapse:collapse;
    border-style:none;
    border-width:0px;
}
/* the sort header link */
th a 
{
    display:block;
    text-decoration:none;
    color:#FFFFFF;
}
/* common cell styles */
th, td
{
    border:1px solid #FFFFFF;
    padding:0.5em;
    text-align:left;
    font-size: 9.7pt;
}
td { cursor:default; }
/* alternating row style */
.alt { background-color:#E5F1F4; }
/* mouseover cell style */
.over { background-color:#ECFBD4; }
/* selected cell style */
.selected
{
    background:#BCE774;
    color:#555;
}
/* mouse-down cell style */
.down
{
    background:#BCE774;
    color:#FFFFFF;
}
/* header cell style */
th, th.over, th.selected, th.down
{
    background:#328AA4 url(img/tr_back.gif) repeat-x;
    color:#FFFFFF;    
}

Create the JavaScript Functions

after the classes were defined, I went ahead and created the JavaScript that would dynamically add and remove these classes at the appropriate time.  To help me with this, I created 2 helper JavaScript functions that given a row or column index, would visit every cell in the row or column.  The second parameter to these functions is a callback that would be invoked that would pass along the cell that was currently being visited.  Here are the listing for these functions ...

function visitColumn(rows, index, callback){
    //  visit all cells in the specified column
    for(var i = 0; i < rows.length; i++){
        callback(rows[i].cells[index]);
    }        
}        

function visitRow(rows, index, callback){
    //  visit all cells in the specified row
    for(var i = 0; i < rows[index].cells.length; i++){
        callback(rows[index].cells[i]);
    }       
} 

once, these functions were created I added a pageLoad event handler to the page.  During the pageLoad event I enumerate all of the cells in the table and attach my event handlers so I can modify the CSS classes as needed ...

function pageLoad(args){

    //  get the elements
    var rows = $get('gvCustomers').getElementsByTagName("tr");
    
    //  attach our event handlers to all non header cells
    for(var i = 0; i < rows.length; i++){
        for(var j = 0; j < rows[i].cells.length; j++){
            if(rows[i].cells[j].tagName != 'TH'){
                
                var td = rows[i].cells[j];
                
                //  on mouseup, remove the 'down' class
                $addHandler(td, 'mouseup', 
                    function(sender){
                        Sys.UI.DomElement.removeCssClass(sender.target, 'down');                            
                    }
                );
                
                //  on mousedown, add the 'down' class
                $addHandler(td, 'mousedown',
                    function(sender){
                        Sys.UI.DomElement.addCssClass(sender.target, 'down');
                    }                        
                );
                
                //  on mouseover, add the 'over' class
                $addHandler(td, 'mouseover',
                    function(sender){
                        visitColumn(rows, sender.target.cellIndex, 
                            function(cell){ Sys.UI.DomElement.addCssClass(cell, 'over'); }
                        );
                        visitRow(rows, sender.target.parentNode.rowIndex, 
                            function(cell){ Sys.UI.DomElement.addCssClass(cell, 'over'); }
                        );            
                    }                        
                );
                
                //  on mouseout, remove the 'over' class
                $addHandler(td, 'mouseout',
                    function(sender){
                        visitColumn(rows, sender.target.cellIndex, 
                            function(cell){ Sys.UI.DomElement.removeCssClass(cell, 'over'); }
                        );
                        visitRow(rows, sender.target.parentNode.rowIndex, 
                            function(cell){ Sys.UI.DomElement.removeCssClass(cell, 'over'); }
                        );            
                    }                        
                );                        
                
                //  on click, add the 'select' class
                $addHandler(td, 'click', 
                    function(sender){
                        //  unselect the cells
                        for(var i = 0; i < rows.length; i++){
                            visitRow(rows, rows[i].rowIndex, 
                                function(cell){ Sys.UI.DomElement.removeCssClass(cell, 'selected'); }
                            );  
                            
                            if(i == 0){
                                for(var j = 0; j < rows[j].cells.length; j++){
                                    visitColumn(rows, j, 
                                        function(cell){ Sys.UI.DomElement.removeCssClass(cell, 'selected'); }
                                    );                        
                                }
                            }
                        }  
               
                        visitColumn(rows, sender.target.cellIndex, 
                            function(cell){ Sys.UI.DomElement.addCssClass(cell, 'selected'); }
                        );
                        visitRow(rows, sender.target.parentNode.rowIndex, 
                            function(cell){ Sys.UI.DomElement.addCssClass(cell, 'selected'); }
                        );              
                    } 
                );
            }
        }
    }
}

that's it.  Enjoy.

Add by : Huobazi (2007-10-29:09:19)