[ASP.NET & jQuery]上下都要有Pager或Button bar的設計

  • 8409
  • 0

[ASP.NET & jQuery]上下都要有Pager或Button bar的設計

前言
在網頁的設計上,還蠻常遇到一個需求是:頁面的上下都要有按鈕或資料分頁,以方便使用者在操作頁面時,不需要為了找按鈕,而一直捲動scroll bar。例如使用ListView來呈現多筆資料,ListView的上下都要有Pager。

這個需求,一般的作法,就是在ListView的上下都放一個Pager,在需要改變時,再一次改變兩個Pager。不過,當Pager是自訂的,上面可能有比較fancy的功能。或是還有其他複雜的user control,也需要放在ListView的上下。這時候,光控制上下的連動,就得花一番功夫。

其實,這是ASP.NET Webform的工程師比較容易被server control的使用想法侷限,問題並沒有這麼複雜,只需要退回以HTML和JavaScript的角度來思考,一切就豁然開朗了。

說明

  1. 抽象意義來說,上面與下面的『元素』其實是同一份『東西』。
  2. server端所有的事件觸發,最後也是透過Render到HTML時,在Attribute, client event還有ASP.NET Webform幫我們偷藏的東西,例如viewstate, eventTarget與eventArguments的hidden等等…讓postback回server端時,server可以模擬與確認,Client剛剛的操作行為是什麼,接著在server端的Page life cycle模擬一次client上的操作。
    也就是,只要你有一份一模一樣的HTML, JavaScript,他們在server端的行為就會一致。


有了以上兩點,這篇的作法相當簡單,重點只有一行:『使用jQuery的clone(),把同一份東西的HTML與JavaScript,複製一份到需要的位置上。』

實作
這邊的例子是ListView,上下要擺Pager與其他Button,結果如下圖:

image

1.  .aspx內容

    <form id="form1" runat="server">
    <div>
        <div id="topDiv">
            <asp:DataPager ID="DataPager1" runat="server" PagedControlID="ListView1" PageSize="6">
                <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="送出" OnClick="Button1_Click" />
        </div>
        <asp:ListView ID="ListView1" runat="server" OnPagePropertiesChanging="ListView1_PagePropertiesChanging">
            <LayoutTemplate>
                <table id="tbLvHeader" runat="server" class="grid" cellpadding="0" cellspacing="0"
                    border="1" style="empty-cells: show;">
                    <tbody>
                        <tr>
                            <td>
                                Person ID
                            </td>
                            <td>
                                Person Name
                            </td>
                        </tr>
                        <tr id="itemPlaceholder" runat="server">
                        </tr>
                    </tbody>
                </table>
            </LayoutTemplate>
            <ItemTemplate>
                <tr id="row" runat="server">
                    <td>
                        <%# Eval("ID")%>
                    </td>
                    <td>
                        <%# Eval("Name")%>
                    </td>
                </tr>
            </ItemTemplate>
        </asp:ListView>
        <div id="bottomDiv">
        </div>
    </div>
    </form>

2. JavaScript

<head runat="server">
    <title></title>
    <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.6.1.js" type="text/javascript"></script>
    <script type="text/javascript">
        $(function () {
            $('div#topDiv').clone(true).appendTo('div#bottomDiv');
        });
    </script>
</head>

3. .aspx.cs

public partial class jQueryClone : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            var data = this.GetData();
            this.ListView1.DataSource = data.ToList<Person>();
            this.ListView1.DataBind();
        }
    }

    private IEnumerable<Person> GetData()
    {
        for (int i = 0; i < 20; i++)
        {
            var entity = new Person { Id = i.ToString(), Name = "Joey" + i.ToString() };
            yield return entity;
        }
    }

    protected void ListView1_PagePropertiesChanging(object sender, PagePropertiesChangingEventArgs e)
    {
        this.DataPager1.SetPageProperties(e.StartRowIndex, e.MaximumRows, false);
        var data = this.GetData();
        this.ListView1.DataSource = data.ToList<Person>();
        this.ListView1.DataBind();
    }

    protected void Button1_Click(object sender, EventArgs e)
    {
        this.Button1.Text = DateTime.Now.ToString();
    }
}

public class Person
{
    public string Id { get; set; }
    public string Name { get; set; }
}

[註]ListView自訂資料來源,搭配DataPager時,請記得在ListView的PagePropertiesChanging事件,重新set DataPager的PageProperties,並且自己在將資料重新繫結到ListView上。

結果
1.不管切換上面或下面的Pager,切到某一頁,上下pager都跟著變

image

2.點上面或下面的送出按鈕,上下按鈕都變成現在的時間
image

結論

  1. 寫ASP.NET Webform, Server control只是輔助開發,一定要去懂最後Web Page就是HTML+JavaScript+CSS,這才是最根本的知識。這樣碰到一些Server control無法達到的需求時,才不會發生明明就只是簡單的HTML, JavaScript概念,卻在server端繞了一大圈硬幹出『貌似』的結果。
     
  2. jQuery的clone()參數代表要不要把相關的event handler也都複製帶過去。在這需求上,通常是要設定成true的。


Sample ProjectjQueryClone.zip

 


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