網友Chuck留言,提了一個關於Super Tables的詭異問題:

暗大您好:

我是用.NET3.5版本開發的,瀏灠器為IE7,程式的
目的是透過ASP.NET的控制項DataGrid顯示多筆資
料,顯示資料的樣貌有純文字和輸入文字方塊和下拉式
選單等等…。問題在於我用了下面這一行敘述:
$(".DetailFlexGrid").toSuperTable({ width: "700px", height: "400px", fixedCols: 1 });
在頁面發生PostBack的事件後,我發現只要是文字方塊
的內容會在舊新值之間附加一個逗號後,再一併顯示在文
字方塊裡面。例如原本是0001,輸入0002,PostBack後
就會顯示0001,0002 ;若如果原本是空白,PostBack後就
會只顯示, ;每PostBack一次,就會再附加一次。
規則如下:(中括號內容為文字方塊的內容)
原本:[0001]
清除[0001]輸入[0002]
第一次PostBack後:[0001,0002]
清除[0001,0002]輸入[0003]
第二次PostBack後:[0001,0002,0003]
似乎會有「舊值和新值用逗號隔開後一併顯示在文字方塊」
上的規則。但我把那行敘述拿掉後,此情況就不會發生了。
想問暗大是什麼原因造成這個問題?

很有趣的現象,沒事TextBox居然自己玩起0001 -> 0001,0002 -> 0001,0002,0003接龍來了?

我用一個很簡單的例子來剖析這個現象。以下的網頁宣告了一個Table,其中放了兩個<asp:TextBox> T1及T2,並用toSuperTable(...)包成可捲動式介面。而在Page_Load裡,放入一段程式在IsPostBack時Response.Write(Request["T1"]);做測試。

<%@ Page Language="C#" %>
<script runat="server">
    protected void Page_Load(object sender, EventArgs e)
    {
        if (Page.IsPostBack) {
            Response.Write(Request["T1"]);
            Response.End();
        }
    }
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <style type="text/css">
    .altRow { background-color: #ddddff; }
    </style>
    <link href="superTables.css" rel="stylesheet" type="text/css" />
    <script type="text/javascript" src="jquery-1.3.1.js"></script>
    <script type="text/javascript" src="superTables.js"></script>
    <script type="text/javascript" src="jquery.superTable.js"></script>
    <script type="text/javascript">
        $(function() {
            //設定SuperTable
            $("#myTable").toSuperTable({ width: "150px", height: "120px", fixedCols: 1});
        });
    </script>
    <style type="text/css">
    .clsLinkButton  
    { font-size: 9pt; cursor: pointer; text-decoration: underline; color: Blue; }
    #rowIdx { width: 20px; text-align: right; }
    #spnCmdBar { font-size: 9pt; margin-left: 15px; }
    </style>
</head>
<body>
    <form id="form1" runat="server">
    <input type="submit" value="Submit" id="btnSubmit" />
    <table id="myTable" border="1">
        <tr><td>No</td><td>Col1</td><td>Col2</td></tr>
        <tr><td>1</td><td><asp:TextBox ID="T1" runat="server" Text="1" /></td><td>T1</td></tr>
        <tr><td>2</td><td><asp:TextBox ID="T2" runat="server" /></td><td>T2</td></tr>
    </table>
    </form>
</body>
</html>

利用IE8的Dev Tools,可以發現一個天大的祕密:

原來Super Table會偷偷複製一份我們的Table,藏在<div class="sFData">區域,所以實際上網頁存在兩個<input name="T1" id="T1" />,上方綠框是網頁初始載入的版本,Value保持在初始值"1",下方紅框是實際可輸入操作的版本,Value會反應輸入值。

當按下Submit時會發生什麼事? 用HttpWatch觀察便可揭曉。當網頁裡有兩個T1,POST送出的內容也會有兩組T1,一組是為原始值1(上圖綠框所指),另一組T1是使用者輸入值2(上圖紅框所指)。而依HTTP的法則,當有多組同名POST或Query String參數,將使用","將多組值組裝成一個字串,由實驗可驗證Request["T1"] == "1,2"。

回到Chuck的案例,網頁載入後一旦套用toSuperTable()便會產生兩組<input>,隱藏版是0001,操作版原本是0001被改成0002,PostBack時就組合成為0001,0002。重新顯示的網頁裡,隱藏版的初值是0001,0002,操作版原本為0001,0002被改成0003,PostBack時再組合成0001,0002,0003,以此類推。

解開了謎團,就不難找出解決之道--在送出前將<div class="sFData">中的隱藏版移除,就可避開它的干擾。試著加入以下的程式碼,在確定要送出表單前移除多餘的輸入元素,就能避免TextBox累加的問題囉!

    <script type="text/javascript">
        $(function() {
            //設定SuperTable
            $("#myTable").toSuperTable({ width: "150px", height: "120px", fixedCols: 1});
            $("#btnSubmit").click(function() {
                //確定送出要離開本頁面時才可執行,不然會導致SuperTable失效
                $("div.sFData").empty();
            });
        });
    </script>

Comments

# by chuck

謝謝暗大的回答,找出問題的癥結點,終於知道為什麼會 有文字「接龍」的情況了,因為一般都不會設定兩個控制項的id值是相同的~又上了一課~~

# by Spell

剛好遇到同樣的問題,感謝暗大的分享!!

# by 泡泡

謝謝暗大! 可是!如果表格有用到 freeze-col 功能的話 (fixCol > 0) 問題好像沒解決到 @@!

# by Jeffrey

to 泡泡,是指freeze-col中也有<input>嗎? 理論上就算有<input>也會在<div class="sFData">的範圍內,應該也會被$("div.sFData").empty()所清除才對。看你要不要進一步提供可重現茶包的範例。

# by 泡泡

對, 我說的是指freeze-col中也有<input>... $("div.sFData").empty() 這招是把"接龍"解決了 可是, freeze-col 內的值就是不給我更新 u.u 無論我寫什麼在上邊,它就只會拿著一開始載入時的值... 不在 freeze-col 內的東西全都正常 @@

# by Jeffrey

to 泡泡,請參考: http://blog.darkthread.net/post-2011-07-02-supertable-postback-fix.aspx

Post a comment