关于Ajax无刷新分页技术的一些研究 c#
小弟新手,求大神有更好的解决方案,指教下~
以前做项目,用过GridView的刷新分页,也用过EasyUI的封装好的分页技术,最近在老项目的基础上加新功能,迫于需求,自己没事琢磨了个Ajax无刷新分页技术,
也在百度看了下, 写的都不是很系统,在这里写个系统的,简单的,方便大家研究下。
系统支持 和数据库交互的无刷新分页、删除后的 当前页 定位、在查询条件下的 分页 ,有数据,显示删除,列表,没有只显示新增按钮。
项目采取的后台拼html,图了个简单,方便区分分页js,在后台写html,增加服务器压力,第一选择还是传JSON哈,谢谢楼下大神回答。
我写的这个无刷新分页用的最重要的sql 语句就是
sql = @"select * from (select ROW_NUMBER() over (ORDER BY CREATEDATE) rownum,a.goodsid,a.goodsname,a.itemname,a.price FROM GoodsOrderAccept a " + selectsql + ") t where t.rownum>='" + ((page - 1) * 10 + 1) + "' and t.rownum<='" + page * 10 + "'";
相信有些大神,看到这里,已经知道我采取的什么方法了,重点就是 ROW_NUMBER(),利用它和Page变量,从前台页面请求不同的页码,显示不同的数据。
下面看一下项目的目录结构:
List.aspx就是页面,Page.ashx就是实现的分页技术,JSONObject.cs在后台对JSON序列化成对象。
List.aspx页面执行如下:
如页面所示,支持checkbox,单删除,多删除.
下面开始贴代码:
List.aspx页面代码如下:
1 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="List.aspx.cs" Inherits="AjaxPage.List" %> 2 3 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 4 <html xmlns="http://www.w3.org/1999/xhtml"> 5 <head runat="server"> 6 <script src="Scripts/jquery-1.4.1.js" type="text/javascript"></script> 7 <title>分页功能演示</title> 8 <script type="text/javascript"> 9 $(function () { 10 11 //初始化首页数据以及各种变量 12 $.ajax({ 13 type: "POST", 14 url: "Page.ashx", 15 dataType: "json", 16 data: { 17 action: "getFirstPageAndVariable" 18 }, 19 success: function (data) { 20 if (data.outStr != "" && data.pagecount != "0") { 21 //有数据加载数据列表,显示数据列表,显示删除按钮,以及分页按钮 22 document.getElementById('btn_delete').style.display = ""; 23 document.getElementById('div_list').style.display = ""; 24 document.getElementById('div_page').style.display = ""; 25 $("#tbody_list").empty(); 26 $("#tbody_list").append(data.outStr); 27 //把总页数赋值给变量 28 $('#<%=hid_last.ClientID %>').val(data.pagecount); 29 //初始化页数输入框 30 $("#text_page").val($('#<%=hid_shou.ClientID %>').val()); 31 //将上一页和下一页变量赋值为首页变量 32 $('#<%=hid_change.ClientID %>').val($('#<%=hid_shou.ClientID %>').val()); 33 } 34 } 35 }); 36 //绑定按钮事件 37 $("#btn_search").bind("click", btn_search); 38 $("#btn_delete").bind("click", btn_delete); 39 //查询事件 40 function btn_search(event) { 41 42 //查询输入框不为空的话,才执行查询事件 43 //if ($("#text_search").val().toString().replace(/[ ]/g, "") != "") { 44 $.ajax({ 45 type: "POST", 46 url: "Page.ashx", 47 dataType: "json", 48 data: { 49 action: "getFirstPageAndVariable", 50 search: $("#text_search").val() 51 }, 52 success: function (data) { 53 if (data.outStr != "" && data.pagecount != "0") { 54 //有数据加载数据列表,显示数据列表,显示删除按钮,以及分页按钮 55 document.getElementById('btn_delete').style.display = ""; 56 document.getElementById('div_list').style.display = ""; 57 document.getElementById('div_page').style.display = ""; 58 $("#tbody_list").empty(); 59 $("#tbody_list").append(data.outStr); 60 //把总页数赋值给变量 61 $('#<%=hid_last.ClientID %>').val(data.pagecount); 62 //初始化页数输入框 63 $("#text_page").val($('#<%=hid_shou.ClientID %>').val()); 64 //模糊查询后,将上一页和下一页变量赋值为首页变量 65 $('#<%=hid_change.ClientID %>').val($('#<%=hid_shou.ClientID %>').val()); 66 } 67 } 68 }); 69 //} 70 } 71 //删除事件 72 function btn_delete(event) { 73 var deleteData = ""; 74 $("#tbody_list tr").each(function () { 75 if ($($(this).children().get(0)).find("input")[0].status) { 76 deleteData += $($(this).children().get(0)).find("input")[0].value + "," + $($(this).children().get(0)).find("input")[0].value + "|"; 77 } 78 }); 79 if (deleteData == "") { 80 alert("不能提交空数据!"); 81 return false; 82 } 83 if (!confirm("确定要删除吗?")) { 84 return false; 85 } 86 $.ajax({ 87 type: "POST", 88 url: "Page.ashx", 89 dataType: "json", 90 data: { 91 action: "deleteData", 92 deleteData: deleteData 93 }, 94 success: function (data) { 95 if (data.status == "success") { 96 //初始化当前页数据以及各种变量 97 $.ajax({ 98 type: "POST", 99 url: "Page.ashx", 100 dataType: "json", 101 data: { 102 action: "getDeletePageAndVariable", 103 hid_change: $('#<%=hid_change.ClientID %>').val(), 104 search: $("#text_search").val() 105 }, 106 success: function (data) { 107 if (data.pagecount != "0") { 108 $("#tbody_list").empty(); 109 $("#tbody_list").append(data.outStr); 110 //把总页数赋值给变量 111 $('#<%=hid_last.ClientID %>').val(data.pagecount); 112 //初始化页数输入框 113 $("#text_page").val(data.hid_change); 114 //将上一页和下一页变量赋值为首页变量 115 $('#<%=hid_change.ClientID %>').val(data.hid_change); 116 } 117 } 118 }); 119 } 120 } 121 }); 122 } 123 //加载首页点击事件 124 $("#a_shou").click(function () { 125 $.ajax({ 126 type: "POST", 127 url: "Page.ashx", 128 dataType: "json", 129 data: { 130 action: "clickPageAndGetData", 131 page: $('#<%=hid_shou.ClientID %>').val(), 132 search: $("#text_search").val() 133 }, 134 success: function (data) { 135 if (data.outStr != "") { 136 $("#tbody_list").empty(); 137 $("#tbody_list").append(data.outStr); 138 $("#text_page").val($('#<%=hid_shou.ClientID %>').val()); 139 //将上一页和下一页的变量赋值为首页变量 140 $('#<%=hid_change.ClientID %>').val($('#<%=hid_shou.ClientID %>').val()); 141 } 142 } 143 }); 144 }); 145 //加载末页点击事件 146 $("#a_last").click(function () { 147 $.ajax({ 148 type: "POST", 149 url: "Page.ashx", 150 dataType: "json", 151 data: { 152 action: "clickPageAndGetData", 153 page: $('#<%=hid_last.ClientID %>').val(), 154 search: $("#text_search").val() 155 }, 156 success: function (data) { 157 if (data.outStr != "") { 158 $("#tbody_list").empty(); 159 $("#tbody_list").append(data.outStr); 160 $("#text_page").val($('#<%=hid_last.ClientID %>').val()); 161 //将上一页和下一页的变量赋值为首页变量 162 $('#<%=hid_change.ClientID %>').val($('#<%=hid_last.ClientID %>').val()); 163 } 164 } 165 }); 166 }); 167 //加载上一页点击事件 168 $("#a_back").click(function () { 169 //当前页面为首页时,无上一页事件 170 var back = parseInt($('#<%=hid_change.ClientID %>').val()) - 1; 171 if (back != 0) { 172 $.ajax({ 173 type: "POST", 174 url: "Page.ashx", 175 dataType: "json", 176 data: { 177 action: "clickPageAndGetData", 178 page: back, 179 search: $("#text_search").val() 180 }, 181 success: function (data) { 182 if (data.outStr != "") { 183 $("#tbody_list").empty(); 184 $("#tbody_list").append(data.outStr); 185 $('#<%=hid_change.ClientID %>').val(back); 186 $("#text_page").val(back); 187 } 188 } 189 }); 190 } 191 }); 192 //加载下一页点击事件 193 $("#a_next").click(function () { 194 //当前页面为最后一页时,无下一页事件 195 var next = parseInt($('#<%=hid_change.ClientID %>').val()) + 1; 196 if ($('#<%=hid_change.ClientID %>').val() != $('#<%=hid_last.ClientID %>').val()) { 197 $.ajax({ 198 type: "POST", 199 url: "Page.ashx", 200 dataType: "json", 201 data: { 202 action: "clickPageAndGetData", 203 page: next, 204 search: $("#text_search").val() 205 }, 206 success: function (data) { 207 if (data.outStr != "") { 208 $("#tbody_list").empty(); 209 $("#tbody_list").append(data.outStr); 210 $('#<%=hid_change.ClientID %>').val(next); 211 $("#text_page").val(next); 212 } 213 } 214 }); 215 } 216 }); 217 //加载确定点击事件 218 $("#a_ok").click(function () { 219 $.ajax({ 220 type: "POST", 221 url: "Page.ashx", 222 dataType: "json", 223 data: { 224 action: "clickPageAndGetData", 225 page: $("#text_page").val(), 226 search: $("#text_search").val() 227 }, 228 success: function (data) { 229 if (data.outStr != "") { 230 $("#tbody_list").empty(); 231 $("#tbody_list").append(data.outStr); 232 $('#<%=hid_change.ClientID %>').val($("#text_page").val()); 233 } 234 } 235 }); 236 }); 237 }); 238 var record = { 239 num: "" 240 } 241 var checkDecimal = function (n) { 242 var decimalReg = /^[0-9]*[1-9][0-9]*$/; 243 if (n.value != "" && decimalReg.test(n.value)) { 244 record.num = n.value; 245 } else { 246 if (n.value != "") { 247 n.value = record.num; 248 } 249 } 250 } 251 </script> 252 </head> 253 <body> 254 <form id="form_page" runat="server"> 255 <!--页面顶部--> 256 <div id="div_tool"> 257 <table width="100%" id="table_tool"> 258 <tr> 259 <td width="50%" style="text-align: center"> 260 请输入食材名称: 261 <input type="text" id="text_search" /> 262 </td> 263 <td width="25%"> 264 <input type="button" value="查询" id="btn_search" /> 265 </td> 266 <td width="25%"> 267 <input type="button" value="删除" style="display: none" id="btn_delete" /> 268 </td> 269 </tr> 270 </table> 271 </div> 272 <br /> 273 <!--页面主题部分--> 274 <div id="div_list" style="display: none"> 275 <table width="100%" id="table_list"> 276 <thead> 277 <tr> 278 <th width="25%"> 279 选择 280 </th> 281 <th width="25%"> 282 食材名称 283 </th> 284 <th width="25%"> 285 食材单位 286 </th> 287 <th width="25%"> 288 食材单价 289 </th> 290 </tr> 291 </thead> 292 <tbody id="tbody_list"> 293 </tbody> 294 </table> 295 </div> 296 <!--始终保持在页面底部--> 297 <div id="div_page" style="position: absolute; bottom: 0; display: none"> 298 <table width="100%"> 299 <tr> 300 <td style="text-align: center; width: 100%"> 301 <a href="#" id="a_shou">首页</a> <a href="#" id="a_back">上一页</a> 302 <input type="text" id="text_page" style="width: 50px;" onkeyup="checkDecimal(this)" /> 303 <a href="#" id="a_next">下一页</a> <a href="#" id="a_last">末页</a> <a href="#" id="a_ok"> 304 确定</a> 305 </td> 306 </tr> 307 </table> 308 </div> 309 <!--记录点击首页的变量,始终为1--> 310 <asp:HiddenField ID="hid_shou" runat="server" Value="1" /> 311 <!--记录点击上一页和下一页的变量--> 312 <asp:HiddenField ID="hid_change" runat="server" /> 313 <!--记录点击末页的变量--> 314 <asp:HiddenField ID="hid_last" runat="server" /> 315 </form> 316 </body> 317 </html>
开始插入 Page.ashx代码:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Data.SqlClient; 6 using System.Data; 7 8 namespace AjaxPage 9 { 10 /// <summary> 11 /// Page 的摘要说明,10条数据分页 12 /// </summary> 13 public class Page : IHttpHandler 14 { 15 16 public void ProcessRequest(HttpContext context) 17 { 18 context.Response.ContentType = "text/plain"; 19 20 JSONObject jo = new JSONObject(); 21 //取得页面发出的动作 22 string action = context.Request["action"]; 23 //取得页面的查询条件 24 string search = context.Request["search"]; 25 SqlDataAdapter ad = null; 26 DataSet dsPagecount = new DataSet(); 27 DataSet dsOutstr = new DataSet(); 28 DataTable dt = new DataTable(); 29 string sql = ""; 30 string connectstring = "server=localhost;User ID=sa;Password=1;database=SqcpDB;Connection Reset=FALSE"; 31 String outStr = String.Empty; 32 string selectsql = ""; 33 //页面有查询条件 34 if (search != "") 35 { 36 selectsql = " where goodsname like '%" + search + "%' "; 37 } 38 //初始化页面以及首页内容 39 if (action == "getFirstPageAndVariable") 40 { 41 sql = @"select count(goodsid) from GoodsOrderAccept" + selectsql; 42 ad = new SqlDataAdapter(sql, connectstring); 43 ad.Fill(dsPagecount); 44 dt = dsPagecount.Tables[0]; 45 //取得数据总条数 46 int count = Convert.ToInt32(dt.Rows[0][0]); 47 //每页10条记录,取得总页数逻辑 48 int pagecount = count / 10; 49 if (count % 10 != 0) 50 { 51 pagecount++; 52 } 53 jo.Add("pagecount", pagecount.ToString()); 54 sql = @"select * from (select ROW_NUMBER() over (ORDER BY CREATEDATE) rownum,a.goodsid,a.goodsname,a.itemname,a.price FROM GoodsOrderAccept a " + selectsql + ") t where t.rownum>=0 and t.rownum<=10"; 55 ad = new SqlDataAdapter(sql, connectstring); 56 ad.Fill(dsOutstr); 57 dt = dsOutstr.Tables[0];//初始加载首页10条数据 58 if (null != dt && dt.Rows.Count != 0) 59 { 60 foreach (DataRow dr in dt.Rows)//遍历dt以html的格式输出内容 61 { 62 outStr += "<tr>"; 63 //给checkbox设置value属性,方便删除 64 outStr += String.Format("<td style='text-align:center'><input type='checkbox' value='{0}' /></td>", dr["goodsid"]); 65 outStr += String.Format("<td style='text-align:center'>{0}</td>", dr["goodsname"]); 66 outStr += String.Format("<td style='text-align:center'>{0}</td>", dr["itemname"]); 67 outStr += String.Format("<td style='text-align:center'>{0}</td>", dr["price"]); 68 outStr += "</tr>"; 69 } 70 } 71 jo.Add("outStr", outStr); 72 context.Response.Write(JSONConvert.SerializeObject(jo)); 73 } 74 //点击分页按钮时,执行的动作 75 else if (action == "clickPageAndGetData") 76 { 77 string pagestr = context.Request["page"]; 78 int page = Convert.ToInt32(pagestr); 79 sql = @"select * from (select ROW_NUMBER() over (ORDER BY CREATEDATE) rownum,a.goodsid,a.goodsname,a.itemname,a.price FROM GoodsOrderAccept a " + selectsql + ") t where t.rownum>='" + ((page - 1) * 10 + 1) + "' and t.rownum<='" + page * 10 + "'"; 80 ad = new SqlDataAdapter(sql, connectstring); 81 ad.Fill(dsOutstr); 82 dt = dsOutstr.Tables[0]; 83 if (null != dt && dt.Rows.Count != 0) 84 { 85 foreach (DataRow dr in dt.Rows)//遍历dt以html的格式输出内容 86 { 87 outStr += "<tr>"; 88 //给checkbox设置value属性,方便删除 89 outStr += String.Format("<td style='text-align:center'><input type='checkbox' value='{0}' /></td>", dr["goodsid"]); 90 outStr += String.Format("<td style='text-align:center'>{0}</td>", dr["goodsname"]); 91 outStr += String.Format("<td style='text-align:center'>{0}</td>", dr["itemname"]); 92 outStr += String.Format("<td style='text-align:center'>{0}</td>", dr["price"]); 93 outStr += "</tr>"; 94 } 95 } 96 jo.Add("outStr", outStr); 97 context.Response.Write(JSONConvert.SerializeObject(jo)); 98 } 99 //点击删除按钮时,执行的动作 100 else if (action == "deleteData") 101 { 102 String[] postDatas = context.Request["deleteData"].Split("|".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); 103 SqlConnection conn = new SqlConnection(connectstring); 104 conn.Open(); 105 foreach (String pd in postDatas) 106 { 107 String[] pdArr = pd.Split(",".ToCharArray()); 108 sql = @"delete from GoodsOrderAccept where goodsid='" + pdArr[0] + "'"; 109 SqlCommand cmd = new SqlCommand(sql, conn); 110 cmd.ExecuteNonQuery(); 111 } 112 conn.Close(); 113 jo.Add("status", "success"); 114 context.Response.Write(JSONConvert.SerializeObject(jo)); 115 } 116 //删除成功后,固定到当前页 117 else if (action == "getDeletePageAndVariable") 118 { 119 string hid_changestr = context.Request["hid_change"]; 120 int hid_change = Convert.ToInt32(hid_changestr); 121 sql = @"select count(goodsid) from GoodsOrderAccept" + selectsql; 122 ad = new SqlDataAdapter(sql, connectstring); 123 ad.Fill(dsPagecount); 124 dt = dsPagecount.Tables[0]; 125 int count = Convert.ToInt32(dt.Rows[0][0]); 126 int pagecount = count / 10; 127 if (count % 10 != 0) 128 { 129 pagecount++; 130 } 131 jo.Add("pagecount", pagecount.ToString());//每页10条记录,取得总页数 132 if (hid_change > pagecount) 133 { 134 hid_change = pagecount; 135 } 136 jo.Add("hid_change", hid_change.ToString()); 137 sql = @"select * from (select ROW_NUMBER() over (ORDER BY CREATEDATE) rownum,a.goodsid,a.goodsname,a.itemname,a.price FROM GoodsOrderAccept a " + selectsql + ") t where t.rownum>='" + ((hid_change - 1) * 10 + 1) + "' and t.rownum<='" + hid_change * 10 + "'"; 138 ad = new SqlDataAdapter(sql, connectstring); 139 ad.Fill(dsOutstr); 140 dt = dsOutstr.Tables[0]; 141 if (null != dt && dt.Rows.Count != 0) 142 { 143 foreach (DataRow dr in dt.Rows)//遍历dt以html的格式输出内容 144 { 145 outStr += "<tr>"; 146 //给checkbox设置value属性,方便删除 147 outStr += String.Format("<td style='text-align:center'><input type='checkbox' value='{0}' /></td>", dr["goodsid"]); 148 outStr += String.Format("<td style='text-align:center'>{0}</td>", dr["goodsname"]); 149 outStr += String.Format("<td style='text-align:center'>{0}</td>", dr["itemname"]); 150 outStr += String.Format("<td style='text-align:center'>{0}</td>", dr["price"]); 151 outStr += "</tr>"; 152 } 153 } 154 jo.Add("outStr", outStr); 155 context.Response.Write(JSONConvert.SerializeObject(jo)); 156 } 157 } 158 159 public bool IsReusable 160 { 161 get 162 { 163 return false; 164 } 165 } 166 } 167 }