All articles| All Pictures| All Softwares| All Video| Go home page| Write articles| Upload pictures

Reading number is top 10 articles
实例解析:减少SQL日志大小的三个好方法_[SQL Server教程]
计算两者相差几个月零几天_[PHP教程]
ASP.NET,2.0高级数据处理之处理Null值_.net资料_编程技术
利用Visual,C#实现任务栏通知窗口_[Asp.Net教程]
SQL循序渐进(13)ORDER,BY子句_[SQL,Server教程]
GridView的各种用法(2)_[Asp.Net教程]
如何实现SQL Server 2005快速web分页_[SQL Server教程]
从XML文件中读取数据绑定到DropDownList_[Asp.Net教程]
网页最简短的拖动对象代码实例演示_JavaScript技术_编程技术
GridView中如何使用CommandField删除时,弹出确认框_[Asp.Net教程]
Reading number is top 10 pictures
每天进步一点点
NeedWallpaper13
China railway shunting skills competition
Men's and women's orgasms
The money of more than 100 countries and regions20
这张图有两句话,你看出来了吗?
China's zhejiang university to create the world's most light material
中国处女图鉴2
[猫扑大杂烩]华东师范墙上看到的捐精告示 15毫升3600元
Get girl by your hand
Download software ranking
Eclipse 4.2.1 For Win32
Red cliff
Adobe Flash Player(IE) 10.0.32.18 浏览器专用的FLASH插件
电车之狼R
Macromedia Dreamweaver 8
Boxer Classic video2
天龙八部十二宫服务端
Call Of Duty2
Tram sex maniac 2 (H) rar bag17
Visual C++界面编程技术
归海一刀 published in(发表于) 2014/3/16 2:54:25 Edit(编辑)
开发一个适合Ajax+JSON+jQuery环境使用的多功能页码栏——jPagerBar-1.1.1_[AJAX教程]

开发一个适合Ajax+JSON+jQuery环境使用的多功能页码栏——jPagerBar-1.1.1_[AJAX教程]

开发一个适合Ajax+JSON+jQuery环境使用的多功能页码栏——jPagerBar-1.1.1_[AJAX教程]

事由:由于最近在测试开发的一个ASP.NET MVC的项目需要用到页码栏(并且需要用到AJAX+JSON传输数据),而微软发布的.NET3.5 CTP 的MVCTOOLKIT里面又没有提供,网上找了下似乎也没有太称心的,于是就自己动手做一个。

由于这个项目用到页码栏的地方大多是后台,所以既然不考虑SEO,本着效率第一的原则,决定全部使用js(jQuery)+Ajax+JSON的模式。我把js开发框架确定在了jQuery上。起先想叫“jPager”,想起来好像JAVA已经有一个JPager了,那就叫jPagerBar。


先确定一下这个插件在项目中必须满足的几个要求:


1、页数不确定,根据记录条数和每页显示记录数自动生成


2、样式不确定,必须可以根据页面需要应用不同样式


3、必须可以自动缩略多余的页码,比如总共有100页,当浏览第50页时,可以省略1-49及51-100之间的部分页码,并且这个延伸显示的页码数量可以由自己设定


4、提供“上一页”“下一页”按钮,并且可以自己设定对应的值或图形


5、记录为空时,隐藏页栏,显示友好的空记录信息


6、属于附加要求:由于该空间可能用于不提供AJAX/JSON数据的页面或者由于配合SEO需要,同时兼顾POST+AJAX方式和GET直接请求页面(如.aspx)两种方式,并且逻辑和输出尽量分离以便日后需要直接HTML输出时(SEO需要),由js转换为C#语言。


7、同一页面中可以多次重复调用,互不影响,并兼容IE/FF


这里先列出完成以上几点必须提供的API,然后我会把源代码全部发上来:


调用:ShowPageBar([containerId] ,[url] , [attr]);


解释:


参数名称


类型


说明


containerId


字符串


提供装载页码栏的容器标签的客户端ID(用于定位,如div)


url


字符串


如果使用GET方法请求页面(最普通的页码栏换页方式),提供需要请求的URL(如果为POST,此url可为空值,有页面指定,稍后源代码中可见)


attr


hashtable


页码栏参数,为hash数据具体包括如下表“表二”


表二 attr hash参数说明:


[attr]参数名称


类型


说明


style


字符串


css样式,默认”technorati”等,可自己设置(我的示例中使用了网上提供的一套Web2.0的样式,大家也可以自己定制)


totalCount


整数


总记录条数


pageCount


整数


没页显示记录条数,默认为20


showPageNumber


整数


缩略显示页码的阀值(如页码为50,则相邻只显示50 - showPageNumber到50 +showPageNumber的页码),默认为3


currentPageIndex


整数


当前页码


onclick


字符串


页码单击事件(如果采用单击事件,并且包含“return false”字段,则url将被忽略),插件会把“{pageindex}”自动替换为当前页码


barMark


字符串


数据显示区域的Mark标签(),备用


noRecordTip


字符串


如果没有记录,显示的友好提示


preWord


字符造


“上一页”按钮显示的字样


nextWord


字符串


“下一页”按钮显示的字样


jQuery源代码如下(PageBar-1.1.1.js):




/**//*
插件名称:jPagerBar
主要功能:对生成的GridView进行客户端加工,对指定的列进行分组并归类显示,更多新功能还在开发中
当前版本号:1.1.1
发布日期:2008/2/22


作者:TNT2 (SZW on cnblogs) QQ:63408537(加位好友请说明来意) Email:szw2003@163.com www.56MAX.com

版权及相关说明:
1、作者对此插件保留所有权利。本插件本着开源、交流、共同进步的宗旨,以免费形式为大家无偿提供。修改、引用请保留以上说明信息,否则将视同为主动盗用本插件。
2、为保证本插件的完整性、安全性和版本统一性,解决任何单位和个人将此插件代码修改后以个人名义或“jGridViewBar”及类似名称发布,一旦发现,作者将不遗余进行力地进行追查、打击、曝光
3、作者对此插件保留最终解释权。


如有任何问题或意见、建议,欢迎与作者取得联系!让我们共同进步!
======================================================================================================================
*/


function ShowPageBar(containerId , url , attr)
{


var style = (attr["style"] == null)? "technorati" : attr["style"];//class样式
var totalCount =( attr["totalCount"]==null || attr["totalCount"] == 0) ? 0 : attr["totalCount"];;//parseInt()//总记录条数
var pageCount = (attr["pageCount"] == null || attr["pageCount"] == 0) ? 20 : attr["pageCount"];//attr["pageCount"];//每页记录数
var showPageNumber = (attr["showPageNumber"] == null || attr["showPageNumber"] == 0) ? 20 : attr["showPageNumber"];//attr["showPageNumber"];//显示页码数量
var currentPageIndex = attr["currentPageIndex"];//当前页
var onclick = attr["onclick"];//onclick参数,如果包含“return false”,则连接转为跳到barMark(暂留接口,其实return false后一般情况下href将失效。)
var barMark = attr["mark"];//onclick后跳转到的标签
var noRecordTip = attr["noRecordTip"];//没有记录提示(支持HTML)
var preWord = (attr["preWord"] == null)? " < " : attr["preWord"];//上一条记录文字,默认为“ < ”
var nextWord = (attr["nextWord"] == null)? " > " : attr["nextWord"];//下一条记录文字,默认为“ > ”

//输出设置
var barID = containerId + "_pageBar";
//var barDiv = ("#"+barID);
//添加PageBar层
("#"+containerId).html("
");
//输出设置 结束

//如果没有记录,返回空记录提示
if(totalCount==0)
{
("#"+barID).html(noRecordTip);
return false;
}

pageCount = (pageCount == null || pageCount == 0) ? 20 : pageCount;//每页显示记录数
var totalPage = parseInt((totalCount-1) / pageCount) +1;//总页数

showPageNumber = (showPageNumber == null || showPageNumber == 0) ? 3 : showPageNumber;
currentPageIndex = (currentPageIndex == null || currentPageIndex <= 0 || currentPageIndex > totalPage) ? 1 : currentPageIndex;


var backPageStyle = (currentPageIndex <= 1) ? "disabled" : "";
var nextPageStyle = (currentPageIndex >= totalPage) ? "disabled" : "";


var firstDisplayPageEnd = 0;//从第1页显示到xx页
var bodyDisplayPageStart = 0;//当前页临近最左页码
var bodyDisplayPageEnd = 0;//当前页临近最右页码
var endDisplayPageStart = 0;//从第xx页显示到最后一页


//设定 bodyDisplayPageStart
bodyDisplayPageStart = (currentPageIndex - showPageNumber <= 1) ? 1 : currentPageIndex - showPageNumber; // (ViewData.pageIndex - ViewData.showPageNumber <= ViewData.showPageNumber) ? ViewData.showPageNumber + 1 : ViewData.pageIndex - ViewData.showPageNumber;


//设定 bodyDisplayPageEnd
bodyDisplayPageEnd = (currentPageIndex + showPageNumber >= totalPage) ? totalPage : currentPageIndex + showPageNumber;



//设定 firstDisplayPageEnd
if(bodyDisplayPageStart > 1)
{
if(bodyDisplayPageStart - showPageNumber <= 1)
firstDisplayPageEnd = bodyDisplayPageStart - 1;
else
firstDisplayPageEnd = showPageNumber;
}
else
{
firstDisplayPageEnd = 0;
}

//设定 endDisplayPageStart
if(bodyDisplayPageEnd < totalPage)
{
if(bodyDisplayPageEnd + showPageNumber >= totalPage)
endDisplayPageStart = bodyDisplayPageEnd + 1;
else
endDisplayPageStart = totalPage - showPageNumber + 1;
}
else
{
endDisplayPageStart = totalPage + 1;
}


/**//******** 备用算法 Start ********/


// //设定 firstDisplayPageEnd
// if (currentPageIndex - showPageNumber > 0 && bodyDisplayPageStart > currentPageIndex - showPageNumber)
// firstDisplayPageEnd = (showPageNumber >= totalPage) ? 0 : showPageNumber;
// else
// firstDisplayPageEnd = 0;


// //设定 endDisplayPageStart
// if (bodyDisplayPageEnd < totalPage)
// endDisplayPageStart = (bodyDisplayPageEnd + showPageNumber < totalPage) ? totalPage- showPageNumber + 1 : totalPage+1;
// else
// endDisplayPageStart = totalPage+1;
//
// //alert(bodyDisplayPageEnd +"<" +totalCount +"- "+showPageNumber);
// ////设定补充首尾
// if(bodyDisplayPageStart > 1 && firstDisplayPageEnd == 0)
// firstDisplayPageEnd = (bodyDisplayPageStart > showPageNumber)? showPageNumber : bodyDisplayPageStart - 1;
// if(bodyDisplayPageEnd < totalPage && endDisplayPageStart > totalPage)
// endDisplayPageStart = (bodyDisplayPageEnd < totalPage - showPageNumber)? totalCount - showPageNumber + 1 : bodyDisplayPageEnd + 1;//MS第一个判断有点多余 TNT2
/**//******** 备用算法 End ********/


//页面参数设定结束


//开始输出
//alert(("#"+barID).html());


// 上一条
if(currentPageIndex <= 1)
("" + preWord + "").appendTo(("#"+barID));
else
(GetPageLink(currentPageIndex-1,currentPageIndex,preWord,onclick,url,barMark)).appendTo(("#"+barID));


//first
for (var i = 1; i <= firstDisplayPageEnd; i++)
(GetPageLink(i,currentPageIndex,i,onclick,url,barMark)).appendTo(("#"+barID));

//省略号
if (firstDisplayPageEnd + 1 < bodyDisplayPageStart)
(" ").appendTo(("#"+barID));

//body
for (var i = bodyDisplayPageStart; i <= bodyDisplayPageEnd; i++)
(GetPageLink(i,currentPageIndex,i,onclick,url,barMark)).appendTo(("#"+barID));

//省略号
if (bodyDisplayPageEnd + 1 < endDisplayPageStart)
(" ").appendTo(("#"+barID));

//end
for (var i = endDisplayPageStart; i <= totalPage; i++)
(GetPageLink(i,currentPageIndex,i,onclick,url,barMark)).appendTo(("#"+barID));

// >
if(currentPageIndex >= totalPage)
("" + nextWord + "").appendTo(("#"+barID));
else
(GetPageLink(currentPageIndex + 1 ,currentPageIndex,nextWord,onclick,url,barMark)).appendTo(("#"+barID));

//alert(("#"+barID).html());
}


//页码标签链接
function GetPageLink(linkPageIndex ,currentPageIndex,text,onclick,url,barMark)
{
var pageData = "?page=";//string.Format("{0}page=", (Request.QueryString.Count == 0) ? "?" : "&") + "{0}";//页码参数

onclick = (onclick != null)? "onclick=\"" + onclick + "\"" : "";
onclick = onclick.replace("{pageindex}",linkPageIndex);
href = (onclick != null && onclick.indexOf("return false") != -1)?"href=\"#" + barMark + "\" ":"href=\"" + url + pageData + linkPageIndex + "\" ";


var linkHTML = "";

if(linkPageIndex == currentPageIndex)
linkHTML = "" + text + "";
else
linkHTML = "onclick + ">" + text + "";

return linkHTML;
}


我们在HTML中这样调用:



var pageCount = 15;//每页计数
var totalRecord = 0;
var pagerStyle = "flickr";//jPagerBar样式

ShowPageBar("pageDataList1_Pager",//[containerId]
"<%= Request.Url.AbsolutePath %>",//[url]
{style:pagerStyle,mark:"pageDataList1Mark",
totalCount:msg.totalCount,showPageNumber:3,pageCount:pageCount,currentPageIndex:pageIndex,noRecordTip:"没有记录",preWord:"上一页",nextWord:"下一页",
onclick:"TurnToPage({pageindex});return false;"}//[attr]
);


上面代码中的msg是我最后获取的JSON数据,msg.totalCount是一个总记录的计数,在这里您可以从msg.data(JSON数据列表)的计数获取,我在此多加这个totalCount只是为了防止测试过程中数据“失真”而引发的bug的掩盖,特此说明。

一般我们还需要一个Handler来获取JSON数据(Handler1.ashx)已升级:


namespace jPagerBar.Handler
{
/**////


/// codebehindclassname 的摘要说明
///

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class Handler1 : IHttpHandler
{


public void ProcessRequest(HttpContext context)
{


//获取数据


if (context.Request.RequestType == "POST")
{
//设置行为参数
string action = context.Request.Form["action"].ToString();//动作
string kind = (action.StartsWith("g_")) ? action.Replace("g_", string.Empty) : string.Empty;//分类查找 前缀
string orderString = (context.Request.Form["orderby"].ToString());//排序
string order = "ascending";//排序:升序 TOD目前都为升序,这里留一个接口
string orderBy = (!string.IsNullOrEmpty(orderString)) ? orderString.Substring(0, orderString.Length - 2) : "ID";//要排序的字段,如果为空,默认为"ID"
if (orderString.EndsWith("_d"))
{
order = "descending";//排序:降序
}


int pageCount = int.Parse(context.Request.Form["pageCount"].ToString());//每页显示记录数
int pageIndex = int.Parse(context.Request.Form["pageIndex"].ToString());//当前页
int skipRecord = (pageIndex - 1) * pageCount;//跳过记录数



XElement dsXML = CreateDataSorce();//创建并获取模拟数据源


//获取数据
var dsLinq =
(order == "ascending") ?
(from x in dsXML.Descendants("DataTemp")
where ((!string.IsNullOrEmpty(kind)) ? (x.Element("Group").Value == kind) : (x.Element("Group").Value != null))
orderby x.Element(orderBy).Value ascending
select new DataSourceModel()
{
ID = x.Element("ID").Value,
Group = x.Element("Group").Value,
Colum1 = x.Element("Colum1").Value,
Colum2 = x.Element("Colum2").Value,
Colum3 = x.Element("Colum3").Value
})
:
(from x in dsXML.Descendants("DataTemp")
where ((!string.IsNullOrEmpty(kind)) ? (x.Element("Group").Value == kind) : (x.Element("Group").Value != null))
orderby x.Element(orderBy).Value descending
select new DataSourceModel()
{
ID = x.Element("ID").Value,
Group = x.Element("Group").Value,
Colum1 = x.Element("Colum1").Value,
Colum2 = x.Element("Colum2").Value,
Colum3 = x.Element("Colum3").Value
});


int totalCount = dsLinq.Count();//记录总数,在此只起到示范作用,客户端的记录总数可以从JSON数据的data计数获取
//var dsFinalList = (order == "a") ?
// dsLinq.OrderBy(x=>x.).Skip(skipRecord).Take(pageCount).ToList() :
// dsLinq.OrderByDescending(orderby).Skip(skipRecord).Take(pageCount).ToList();


System.Text.StringBuilder sb = new System.Text.StringBuilder();
sb.Append("{");
sb.Append("totalCount:");
sb.Append(totalCount.ToString());
sb.Append(",data:");
sb.Append(ToJSON(dsLinq.Skip(skipRecord).Take(pageCount).ToList()));
sb.Append("}");


context.Response.ContentType = "text/plain";
context.Response.Write(sb.ToString());
context.Response.End();
}


}



//创建数据源(用XML模拟)
private XElement CreateDataSorce()
{
string dataSourceFilePath = HttpContext.Current.Server.MapPath("~/App_Data/DataSource.xml");


if (!File.Exists(dataSourceFilePath))
{
//设置模拟数据源
XElement dsInfos = new XElement("jPagerBar");
Random rdn = new Random();
for (int i = 1; i <= 300; i++)
{
//分类数据(模拟)
//string[] groups = new string[] { "G1", "G2", "G3", "G4" };
string guid=Guid.NewGuid().ToString().Replace("-","");//用Guid产生随机代码
//生成模拟数据
XElement dsInfo = new XElement("DataTemp",
new XElement("ID", i.ToString("000")),
new XElement("Group", "Group"+rdn.Next(0,5).ToString()),
new XElement("Colum1",guid.Substring(0,3) + "_C1 in " + i.ToString()),
new XElement("Colum2", guid.Substring(3,3) + rdn.Next(100).ToString() + "_C2 in " + i.ToString()),
new XElement("Colum3", guid.Substring(6,3) + rdn.Next(100).ToString() + "_C3 in " + i.ToString())
);
dsInfos.Add(dsInfo);//填充数据
}


//保存
dsInfos.Save(dataSourceFilePath);
}


return XElement.Load(dataSourceFilePath);
}


public static string ToJSON(object obj)
{
JavaScriptSerializer serializer = new JavaScriptSerializer();
return serializer.Serialize(obj);
}


//private static void GetJSON(XElement dsXML)
//{
// var dsLinq = (from x in dsXML.Descendants("DataTemp")
// select new DataSourceModel()
// {
// ID = x.Element("ID").Value,
// Group = x.Element("Group").Value,
// Colum1 = x.Element("Colum1").Value,
// Colum2 = x.Element("Colum2").Value,
// Colum3 = x.Element("Colum3").Value
// });
// int totalCount = dsLinq.Count();//记录总数,在此只起到示范作用,客户端的记录总数可以从JSON数据的data计数获取
// System.Text.StringBuilder sb = new System.Text.StringBuilder();
// sb.Append("{");
// sb.Append("totalCount:");
// sb.Append(totalCount.ToString());
// sb.Append(",data:");
// sb.Append(ToJSON(dsLinq.ToList()));
// sb.Append("}");
//}


public bool IsReusable
{
get
{
return false;
}
}
}


//数据源结构
public class DataSourceModel
{
public string ID { get; set; }
public string Group { get; set; }
public string Colum1 { get; set; }
public string Colum2 { get; set; }
public string Colum3 { get; set; }
}
}





上面我用XML模拟了一个数据源,正好顺便尝试了一下Linq to XML:)如果您是使用.NET2.0的话,也可改成XMLDocument的方式或者从自己的数据源获取。

这里我们看一下基本效果:
基本状态:



如果超过相邻页数地阀值的页码用...替代:


下面我们升级一下,可以自定义没页显示得条数和跳至的页码:


光这样当然是不够的,如果用户输入了无效的值,会引发无效的服务器响应,我们需要在客户端就过滤:

一共300条数据,每页10条,只能显示30页,要31页当然就错了。当然这里我的验证过程只是提供了一条思路,还可以有更多的丰富。(咦?光影魔术手不注册还会有水印?)

刚才我说的需要能自定义样式,当然也不能少:


或者这样:

或者这样:






========以下为新增功能


新增筛选、排序功能







这个项目是开源的,大家可以在这里下载:/Files/szw/jPagerBar.rar

友情提醒一下:
1、这个Demo默认为.net3.5,您也可体提取到别的.net版本中运行。
2、这个项目的开发背景是ASP.NET MVC,为了比较直观,我用WebForms创建了这个Demo,如果有什么疏漏,请大家多多包涵,并且不吝指出其中的错误或者可以改进的地方。
3、因为MVC和WebForms的输出方式有所不同,大家在这里可能看不到太多和.NET有关的东西,对应的
.ascx文件我会在jPagerBar最终版本发布后,发布上来,当然大家也可以做成UI。

做这个demo有点匆忙,希望对大家有用,十分期待大家的建议,谢谢!


来源:http://szw.cnblogs.com/







添加到del.icio.us 添加到新浪ViVi 添加到百度搜藏 添加到POCO网摘 添加到天天网摘365Key 添加到和讯网摘 添加到天极网摘 添加到黑米书签 添加到QQ书签 添加到雅虎收藏 添加到奇客发现 diigo it 添加到饭否 添加到飞豆订阅 添加到抓虾收藏 添加到鲜果订阅 digg it 貼到funP 添加到有道阅读 Live Favorites 添加到Newsvine 打印本页 用Email发送本页 在Facebook上分享


Disclaimer Privacy Policy About us Site Map

If you have any requirements, please contact webmaster。(如果有什么要求,请联系站长)
Copyright ©2011-
uuhomepage.com, Inc. All rights reserved.