[ASP.NET]ListView Radio單選列與跨資料分頁記值

  • 9773
  • 0

[ASP.NET]ListView Radio單選列與跨資料分頁記值

前言
在GridView, ListView裡面,很常會有需要放個RadioButton給user單選該列的需求,但是由於在資料繫結的server control裡面,放RadioButton,即使設定Group屬性,仍會因為Render出來的HTML被加載了container的prefix或postfix,而被誤判成不同組的Radio,而失去了單選的效果。

今天這邊,就用很簡單的方式,來解決這個問題。跨頁記住選取值的部分,則只需要JavaScript與Hidden搭配即可。

Solution
Tips:

  1. 因為Server Control在Render的時候,會幫我們加上我們不想要的postfix,所以我們將server control: RadioButton換成HTML control: radio。將原本的Group屬性,換設定radio的name屬性。而Value的部分,我們bind上DataKeys來當作分辨列的PKey。(要小心不要有機敏性資訊)
  2. 當postback後,我們需要記住剛剛HTML radio上選的值,這時候就需要hidden的輔助。(因為是HTML control,所以得自行使用hidden記值,來模擬server control內建的viewstate效果)。這邊我們使用jQuery來進行記值與選取的動作。所以我們要給radio一個class,來幫助我們等等用jQuery的selector做定位。


沒了,基本上就這兩個原則,就可以達到我們的效果。

我們來看.aspx上的code:


<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <script src="Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
    <script type="text/javascript">
        $(document).ready(function () {
            $('input.resend').bind('change', function () {                
                $('#HiddenField1').val($(this).val());
            })
            .each(function () {
                if ($(this).val() == $('#HiddenField1').val()) {
                    $(this).attr("checked", "checked");
                }
            }); ;
        });
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:ListView ID="ListView1" runat="server">
            <LayoutTemplate>
                <table id="tbLvHeader" runat="server" class="grid" cellpadding="0" cellspacing="0"
                    border="1" style="empty-cells: show;">
                    <table>
                        <tr class="head">
                            <th style="width: 8%;">
                                <asp:Label ID="lblPeriod" runat="server" Text="Radio"></asp:Label>
                            </th>
                            <th style="width: 15%;">
                                id
                            </th>
                        </tr>
                        <tr id="itemPlaceholder" runat="server" />
                    </table>
                </table>
            </LayoutTemplate>
            <ItemTemplate>
                <tr id="trTemplate">
                    <td style="width: 8%;">
                        <input id="Radio1" type="radio" name="resend" value='<%# Eval("id")%>' class="resend" />
                    </td>
                    <td style="width: 15%;">
                        <%# Eval("id")%>
                    </td>
                    <tr>
            </ItemTemplate>
        </asp:ListView>
        <asp:DataPager ID="DataPager1" runat="server" PagedControlID="ListView1" OnPreRender="DataPager1_PreRender">
            <Fields>
                <asp:NextPreviousPagerField ButtonType="Button" ShowFirstPageButton="True" ShowNextPageButton="False"
                    ShowPreviousPageButton="False" />
                <asp:NumericPagerField />
                <asp:NextPreviousPagerField ButtonType="Button" ShowLastPageButton="True" ShowNextPageButton="False"
                    ShowPreviousPageButton="False" />
            </Fields>
        </asp:DataPager>
        <asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
        <asp:HiddenField ID="HiddenField1" runat="server" />
    </div>
    </form>
</body>
</html>

JavaScript說明:

  1. 當radio change時,將值assign到hidden。
  2. document.ready()的時候,判斷radio的值跟hidden的值相等時,則選取此radio。

 

Server端則只是搭配DataPager的分頁,以及手動assign資料給ListView時,分頁的功能要寫在DataPager的PreRender事件中,重新binding ListView才會work。而在server端,需要取radio的值時,因為radio是HTML control,所以要透過Request.Form去取。


    protected void Button1_Click(object sender, EventArgs e)
    {
        this.Button1.Text = this.Request.Form["resend"] as string;
    }

    protected void DataPager1_PreRender(object sender, EventArgs e)
    {
        this.ListView1.DataSource = GetDataSource();
        this.ListView1.DataBind();        
    }

    /// <summary>
    /// Gets the data source.
    /// </summary>
    /// <returns></returns>
    /// <history>
    /// 1. Joey Chen, 2011/3/15, 下午 12:20, Created
    /// </history>
    private List<MyObject> GetDataSource()
    {
        List<MyObject> list = new List<MyObject>();
        for (int i = 0; i < 200; i++)
        {
            list.Add(new MyObject { ID = i, Name = "Joey" + i.ToString() });
        }
        return list;
    }

 

畫面

  1. 初始畫面
    image
  2. 當我們選了id為2的那一列,然後選Button,會發現postback完,radio選取值仍保留著,並且在server端取到Radio的Value為2
    image
  3. 當我們選最後一頁時,可以發現最後一頁上的資料,並沒有任何資料被選取
    image
  4. 這個時候,我們再切回第一頁,會發現id為2的資料,仍能維持著選取的狀態
    image


結論
That's all. 簡單吧,相信您也可以很簡單的做到這樣的效果。 希望對

  1. 不知道手動assign listview datasource後,怎麼跟datapager搭配的人
  2. 不知道怎麼在GridView/ListView,設計使用Radio單選的人
  3. 不知道怎麼在ListView跨分頁時,記住剛剛選取值的人

能有所幫助,enjoy it!!

Sample Code: ListViewWithRadio.zip

 


blog 與課程更新內容,請前往新站位置:http://tdd.best/