[ASP.net MVC 4] 自己打造分頁Pager範例程式碼 (下拉選單版,表單Post方式)
前言
把所有頁數都塞進下拉選單,這樣的做法寫的程式碼少,也比較簡單
因為之前有PO過Ajax查詢方式:[ASP.net MVC 4] 自己打造分頁Pager範例程式碼 (數字版,Ajax)
所以這篇就改用表單Post來寫寫看
說明都在程式碼註解裡
實作
Models資料夾加入
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace MvcApplicationPager.Models
{
public class ProductViewModel
{
/// <summary>
/// 編號
/// </summary>
public int No { get; set; }
/// <summary>
/// 名稱
/// </summary>
public string ProductName { get; set; }
/// <summary>
/// 是否上下架
/// </summary>
public bool IsOpen { get; set; }
}
}
Demo用,在Global.asax.cs 塞假資料
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Routing;
namespace MvcApplicationPager
{
// Note: For instructions on enabling IIS6 or IIS7 classic mode,
// visit http://go.microsoft.com/?LinkId=9394801
public class MvcApplication : System.Web.HttpApplication
{
//假裝這是DB撈出來的資料
public static List<ProductViewModel> dbList = new List<ProductViewModel>();
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
#region 塞假資料
Random rand = new Random(Guid.NewGuid().GetHashCode());
for (int i = 1; i <= 104; i++)
{
bool IsOpen = true;//Default
int number = rand.Next(1, 3);//1~2
if (number == 2)
{
IsOpen = false;
}
dbList.Add(new ProductViewModel()
{
No = i,
ProductName = Guid.NewGuid().ToString().Substring(0, 5).ToUpper(),
IsOpen = IsOpen
});
}
#endregion
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
}
}
}
控制器
HomeController.cs
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
//剛剛宣告的
using MvcApplicationPager.Models;
using System.Text;
namespace MvcApplicationPager.Controllers
{
public class HomeController : Controller
{
//準備畫面上下拉選單資料
private void initViewData(string selectValue)
{
//上下架的下拉選單的資料清單
ViewData["IsOpenItems"] = new List<SelectListItem>()
{
new SelectListItem(){ Text="請選擇",Value="-1",Selected=(selectValue=="-1")},
new SelectListItem(){ Text="上架",Value="true" ,Selected=(selectValue=="true")},
new SelectListItem(){ Text="下架",Value="false" ,Selected=(selectValue=="false")},
};
}
[HttpGet]
public ActionResult Index()
{
this.initViewData("-1");
IEnumerable<ProductViewModel> result = this.QueryData(10, 0, new FormCollection());
return View(result);
}
/// <summary>
/// 查詢資料
/// </summary>
/// <returns></returns>
public IEnumerable<ProductViewModel> QueryData(int iPageSize, int iCurrentPageIndex, FormCollection form)
{
var result = from r in MvcApplication.dbList
select r;
if (!string.IsNullOrEmpty(form["sProductName"]))
{//有輸入名稱
result = from r in result
where r.ProductName.Contains(form["sProductName"])
select r;
}
//有輸入上下架
if (form["sIsOpen"] != null && form["sIsOpen"] != "-1")
{
result = from r in result
where r.IsOpen == Convert.ToBoolean(form["sIsOpen"])
select r;
}
//顯示TempData["pager"]
TempData["pager"] = this.pageString(result,iPageSize,iCurrentPageIndex);
//抓DB少量的資料
result = result.Skip(iCurrentPageIndex * iPageSize).Take(iPageSize);
return result;
}
/// <summary>
/// 產生pager字串(這個請再自行抽到其他Utility之類的類別裡)
/// </summary>
/// <param name="result">集合物件</param>
/// <param name="iPageSize">每頁顯示幾筆</param>
/// <param name="iCurrentPageIndex">目前的索引頁</param>
/// <returns></returns>
public string pageString(IEnumerable<object> result,int iPageSize,int iCurrentPageIndex)
{
#region Pager處理(文章重點在這!)
//總筆數
int iRowTotal = result.Count();
//總頁數
int iPageTotal = (iRowTotal / iPageSize);
if (iRowTotal % iPageSize > 0)
{
iPageTotal++;
}
//目前頁數
int iCurrentPage = iCurrentPageIndex + 1;
//防呆
if (iCurrentPage > iPageTotal)
{
iCurrentPage = iPageTotal;
iCurrentPageIndex = iCurrentPage - 1;
}
if (iCurrentPage < 0)
{
iCurrentPage = 1;
iCurrentPageIndex = 0;
}
//要回傳的字串
StringBuilder sb = new StringBuilder();
//第二頁以後才有上一頁
string strPreJS = ((iCurrentPage > 1) ? "javascript:search('" + (iCurrentPage - 1) + "');" : "#");
//顯示總筆數
sb.Append("合計:" + iRowTotal+"筆");
//顯示上一頁
sb.Append("<a href=\"" + strPreJS + "\">← Prev</a>");
//顯示第一頁
sb.Append("<a href=\"javascript:search(1);\">First</a>");
//處理下拉選單
sb.Append("目前第");
sb.Append("<select name='selectCurrentPage' onchange=\"search(this.value);\">");
//把所有頁數塞進下拉選單(從1算起)
for (int i = 1; i <= iPageTotal; i++)
{
bool bSelected = (i==iCurrentPage);//表單Post後,下拉選單要停在剛剛選擇的值
sb.Append("<option value='" + i + "' " + (bSelected ? "selected" : "") + ">" + i + "</option>");
}
sb.Append("</select>");
sb.Append("頁");
//目前頁小於最後一頁,就有下一頁按鈕
string strNextJS = (iCurrentPage < iPageTotal ? "javascript:search('" + (iCurrentPage + 1) + "');" : "#");
//顯示最後一頁
sb.Append("<a href=\"javascript:search(" + iPageTotal + ");\">Last</a>");
//顯示下一頁
sb.Append("<a href=\"" + strNextJS + "\">Next → </a>");
#endregion
return sb.ToString();
}
/// <summary>
/// 表單Post查詢資料
/// </summary>
/// <param name="iPageSize"></param>
/// <param name="iCurrentPageIndex"></param>
/// <returns></returns>
[HttpPost]
public ActionResult Index(FormCollection form)
{
//這裡的int iPageSize, int iCurrentPageIndex參數,前端使用者可能會用F12開發者工具亂改成字串
//怎麼防禦就請自由料理了...
int iPageSize = Convert.ToInt32(form["selectPageSize"]);
int iCurrentPageIndex = (Convert.ToInt32(form["selectCurrentPage"]) - 1);
IEnumerable<ProductViewModel> result = this.QueryData(iPageSize, iCurrentPageIndex, form);
//下拉選單剛剛選擇的值要keep住
ViewData["iPageSize"] = iPageSize;
this.initViewData(form["sIsOpen"]);
return View(result);
}
}
}
View的Index.cshtml
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Demo下拉選單分頁(Post版)</title>
<script type="text/javascript" src="@Url.Content("~/Scripts/jquery-2.0.0.min.js")"></script>
@*複製範例時候,這個css可以刪除*@
<style type="text/css">
/*讓pager各超連結間有空隔*/
#divPager a {
margin: 2px;
}
</style>
<script type="text/javascript">
//表單Post查詢
function search(pageNumber) {
//記下目前頁數
// $("select[name='selectCurrentPage']")來自Controller端組成的分頁字串
$("select[name='selectCurrentPage']").val(pageNumber);
//提交表單
$("form[name='myForm']").submit();
}
</script>
</head>
<body>
@using (Html.BeginForm("Index", "Home", FormMethod.Post, new { name = "myForm" }))
{
<div>
名稱:@Html.TextBox("sProductName")<br />
上下架:@Html.DropDownList("sIsOpen", (IEnumerable<SelectListItem>)ViewData["IsOpenItems"])<br />
每頁顯示幾筆:@Html.DropDownList("selectPageSize", new List<SelectListItem>() {
new SelectListItem(){ Text="10",Value="10",Selected=(Convert.ToInt32(ViewData["iPageSize"]) ==10)},
new SelectListItem(){ Text="30",Value="30",Selected=(Convert.ToInt32(ViewData["iPageSize"]) ==30)},
new SelectListItem(){ Text="50",Value="50",Selected=(Convert.ToInt32(ViewData["iPageSize"]) ==50)},
}, new { onchange = "search(1);" })
@*按下搜尋後,到搜尋結果第1頁*@
<input type="button" value="搜尋" onclick="search(1);" /><br />
</div>
<table cellspacing="0" cellpadding="0" border="1">
<thead>
<tr>
<th>編號</th>
<th>名稱</th>
<th>上下架</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>@item.No</td>
<td>@item.ProductName</td>
<td>@item.IsOpen</td>
</tr>
}
</tbody>
</table>
<br />
@*分頁*@
<div id="divPager">
@Html.Raw(TempData["pager"])
</div>
}
</body>
</html>
執行畫面
結語
本文範例程式碼下載,放到MSDN期滿