[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的角度來思考,一切就豁然開朗了。
說明
- 抽象意義來說,上面與下面的『元素』其實是同一份『東西』。
-
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,結果如下圖:
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都跟著變
2.點上面或下面的送出按鈕,上下按鈕都變成現在的時間
結論
-
寫ASP.NET Webform, Server control只是輔助開發,一定要去懂最後Web Page就是HTML+JavaScript+CSS,這才是最根本的知識。這樣碰到一些Server control無法達到的需求時,才不會發生明明就只是簡單的HTML, JavaScript概念,卻在server端繞了一大圈硬幹出『貌似』的結果。
- jQuery的clone()參數代表要不要把相關的event handler也都複製帶過去。在這需求上,通常是要設定成true的。
Sample Project : jQueryClone.zip
blog 與課程更新內容,請前往新站位置:http://tdd.best/