GridView的標題列凍結效果

應該有不少人被這麼要求過吧?

"你們做的網頁表格為什麼不能像Excel一樣凍結標題列,底下捲來捲去也不會跑掉?"

前陣子看到一個不錯的Javascript Library,只用一行Code就可以輕鬆做出HTML表格列凍結的效果,剛好部門裡也常有這種需求,我就弄了一個簡單的範例。

大家可以先看Scrollable HTML Table Plugin範例,它本來是個純Javascript Library,Plugin只是做了簡單的包裝,把new ScrollableTable()一列指令再包起來,意義不大,所以我的示範裡只使用webtoolkit.scrollabletable.js,省去額外載入webtoolkit.jscrollable.js的功夫。

弄了一個虛構的DataTable,Bind到GridView上,稍作處理再var t = new ScrollableTable($("#GridView1")[0], 400, 640);,就變成以下的樣子:

完整程式碼如下:

<%@ Page Language="C#" %>
<%@ Import Namespace="System.Data" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
    protected void Page_Load(object sender, EventArgs e)
    {
        DataTable t = new DataTable();
        t.Columns.Add("序號", typeof(int));
        t.Columns.Add("料號", typeof(string));
        t.Columns.Add("單價", typeof(decimal));
        t.Columns.Add("數量", typeof(int));
        t.Columns.Add("金額", typeof(decimal), "單價*數量");
        Random rnd = new Random();
        for (int i = 0; i < 200; i++)
        {
            t.Rows.Add(
                i + 1, 
                Guid.NewGuid().ToString().Substring(0, 13).ToUpper(),
                rnd.NextDouble() * 100,
                rnd.Next() * 2000);
        }
        GridView1.AutoGenerateColumns = false;
        foreach (DataColumn c in t.Columns)
        {
            BoundField bf = new BoundField();
            bf.DataField = c.ColumnName;
            bf.HeaderText = c.ColumnName;
            if (c.DataType == typeof(decimal))
                bf.DataFormatString = "{0:#,0.00}";
            else if (c.DataType == typeof(int))
                bf.DataFormatString = "{0:#,0}";
            bf.ItemStyle.HorizontalAlign =
                (!string.IsNullOrEmpty(bf.DataFormatString)) ?
                HorizontalAlign.Right : HorizontalAlign.Center;
                
            GridView1.Columns.Add(bf);
        }
        GridView1.DataSource = t;
        GridView1.DataBind();
    }
</script>
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <style type="text/css">
    #GridView1 tr { border: solid 1px #f0f0f0; }
    #GridView1 td, th { padding: 3px; border: solid 1px white; }
    td, th { padding: 3px; border: solid 1px white; }
    #GridView1 thead tr { background-color: #dddddd; }
    .altRow { background-color: #ddddff; }
    </style>
    <script type="text/javascript" src="jquery-1.3.1.js"></script>
    <script type="text/javascript" src="webtoolkit.scrollabletable.js"></script>
    <script type="text/javascript">
        $(function() {
            $("#GridView1 tr:first").wrap("<thead></thead>");
            $("#GridView1 thead").insertBefore("#GridView1 tbody");
            $("#GridView1 tbody tr:odd").addClass("altRow");
            $("#GridView1").attr("cellspacing", "1");
            var t = new ScrollableTable($("#GridView1")[0], 400, 640);
        });
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <asp:GridView ID="GridView1" runat="server" Font-Size="9pt">
    </asp:GridView>
    </form>
</body>
</html>

由於Scrollable HTML Table需要由<thead>, <tbody>區分凍結區及捲動區,而GridView所產生的HTML Table標題列及內容列都放在<tbody>中且無<thead>,因此要做些事後加工,將標題列提取出來,另外放入新增的<thead>中,程式示範了如何jQuery wrap, insertBefore來解決這個問題,都是酷酷地一步到位,蠻值得參考的。

注意: 此解決方案無法跨瀏覽器,目前測試只有IE6, IE7, FF3可用, 不支援IE8, Safari, Chrome, Opera。

【2009-02-18 更新】找到另一個跨瀏覽器且支援標題欄、列凍結的版本,請見: GridView的標題欄、列凍結效果(跨瀏覽器版)

Published 17 February 2009 03:37 PM 由 Jeffrey
Filed under: , ,


意見

# Eddy said on 17 February, 2009 01:57 AM

在IE8試文章提到的Scrollable HTML Table Plugin範例

, 標題列會跑掉

# Jeffrey said on 17 February, 2009 02:21 AM

to Eddy, 對,忘了加註,Script Library有註明只支援IE 5+(IE8不OK,但當年還不存在,故未註!), FF 1.5+,我補上限制了,謝謝提醒。

# Ammon said on 17 February, 2009 06:38 AM

為了符合jQuery的精神 應該寫成下面這樣才對 XD

new ScrollableTable(

$("#GridView1").attr("cellspacing", "1")

.find("tbody tr:odd").addClass("altRow").end()

.find("tr:first").wrap("<thead></thead>").end()

.find("thead").insertBefore("#GridView1 tbody").end()[0]

, 400, 640);

# Jeffrey said on 17 February, 2009 08:01 AM

to Ammon, 很讚! 很有jQuery的fu~~~ 真的有貫徹"一行打死"的最高境界,哈!

# Ike said on 10 November, 2009 12:43 AM

另外找到加上 thead 的方法

stackoverflow.com/.../how-do-i-get-a-gridview-to-render-thead

你的看法呢?

(必要的) 
(必要的) 
(選擇性的)
(必要的) 

請輸入以上的數字:

搜尋

Go

<February 2009>
SunMonTueWedThuFriSat
25262728293031
1234567
891011121314
15161718192021
22232425262728
1234567
 
RSS
【工商服務】
最新回應

Tags 分類檢視
關於作者

一個醉心技術又酷愛分享的Coding魔人,十年的IT職場生涯,寫過系統、管過專案, 也帶過團隊,最後還是無怨無悔地選擇了技術鑽研這條路,近年來則以做一個"有為的中年人"自許。

文章典藏
其他功能

這個部落格


BlogLook Score and Rank

Syndication