mirror of https://github.com/helloxz/onenav.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
309 lines
8.9 KiB
309 lines
8.9 KiB
/** |
|
|
|
@Name : laypage 分页组件 |
|
@License:MIT |
|
|
|
*/ |
|
|
|
layui.define(function(exports){ |
|
"use strict"; |
|
|
|
var doc = document |
|
,id = 'getElementById' |
|
,tag = 'getElementsByTagName' |
|
|
|
//字符常量 |
|
,MOD_NAME = 'laypage', DISABLED = 'layui-disabled' |
|
|
|
//构造器 |
|
,Class = function(options){ |
|
var that = this; |
|
that.config = options || {}; |
|
that.config.index = ++laypage.index; |
|
that.render(true); |
|
}; |
|
|
|
//判断传入的容器类型 |
|
Class.prototype.type = function(){ |
|
var config = this.config; |
|
if(typeof config.elem === 'object'){ |
|
return config.elem.length === undefined ? 2 : 3; |
|
} |
|
}; |
|
|
|
//分页视图 |
|
Class.prototype.view = function(){ |
|
var that = this |
|
,config = that.config |
|
,groups = config.groups = 'groups' in config ? (config.groups|0) : 5; //连续页码个数 |
|
|
|
//排版 |
|
config.layout = typeof config.layout === 'object' |
|
? config.layout |
|
: ['prev', 'page', 'next']; |
|
|
|
config.count = config.count|0; //数据总数 |
|
config.curr = (config.curr|0) || 1; //当前页 |
|
|
|
//每页条数的选择项 |
|
config.limits = typeof config.limits === 'object' |
|
? config.limits |
|
: [10, 20, 30, 40, 50]; |
|
config.limit = (config.limit|0) || 10; //默认条数 |
|
|
|
//总页数 |
|
config.pages = Math.ceil(config.count/config.limit) || 1; |
|
|
|
//当前页不能超过总页数 |
|
if(config.curr > config.pages){ |
|
config.curr = config.pages; |
|
} |
|
|
|
//连续分页个数不能低于0且不能大于总页数 |
|
if(groups < 0){ |
|
groups = 1; |
|
} else if (groups > config.pages){ |
|
groups = config.pages; |
|
} |
|
|
|
config.prev = 'prev' in config ? config.prev : '上一页'; //上一页文本 |
|
config.next = 'next' in config ? config.next : '下一页'; //下一页文本 |
|
|
|
//计算当前组 |
|
var index = config.pages > groups |
|
? Math.ceil( (config.curr + (groups > 1 ? 1 : 0)) / (groups > 0 ? groups : 1) ) |
|
: 1 |
|
|
|
//视图片段 |
|
,views = { |
|
//上一页 |
|
prev: function(){ |
|
return config.prev |
|
? '<a href="javascript:;" class="layui-laypage-prev'+ (config.curr == 1 ? (' ' + DISABLED) : '') +'" data-page="'+ (config.curr - 1) +'">'+ config.prev +'</a>' |
|
: ''; |
|
}() |
|
|
|
//页码 |
|
,page: function(){ |
|
var pager = []; |
|
|
|
//数据量为0时,不输出页码 |
|
if(config.count < 1){ |
|
return ''; |
|
} |
|
|
|
//首页 |
|
if(index > 1 && config.first !== false && groups !== 0){ |
|
pager.push('<a href="javascript:;" class="layui-laypage-first" data-page="1" title="首页">'+ (config.first || 1) +'</a>'); |
|
} |
|
|
|
//计算当前页码组的起始页 |
|
var halve = Math.floor((groups-1)/2) //页码数等分 |
|
,start = index > 1 ? config.curr - halve : 1 |
|
,end = index > 1 ? (function(){ |
|
var max = config.curr + (groups - halve - 1); |
|
return max > config.pages ? config.pages : max; |
|
}()) : groups; |
|
|
|
//防止最后一组出现“不规定”的连续页码数 |
|
if(end - start < groups - 1){ |
|
start = end - groups + 1; |
|
} |
|
|
|
//输出左分割符 |
|
if(config.first !== false && start > 2){ |
|
pager.push('<span class="layui-laypage-spr">…</span>') |
|
} |
|
|
|
//输出连续页码 |
|
for(; start <= end; start++){ |
|
if(start === config.curr){ |
|
//当前页 |
|
pager.push('<span class="layui-laypage-curr"><em class="layui-laypage-em" '+ (/^#/.test(config.theme) ? 'style="background-color:'+ config.theme +';"' : '') +'></em><em>'+ start +'</em></span>'); |
|
} else { |
|
pager.push('<a href="javascript:;" data-page="'+ start +'">'+ start +'</a>'); |
|
} |
|
} |
|
|
|
//输出输出右分隔符 & 末页 |
|
if(config.pages > groups && config.pages > end && config.last !== false){ |
|
if(end + 1 < config.pages){ |
|
pager.push('<span class="layui-laypage-spr">…</span>'); |
|
} |
|
if(groups !== 0){ |
|
pager.push('<a href="javascript:;" class="layui-laypage-last" title="尾页" data-page="'+ config.pages +'">'+ (config.last || config.pages) +'</a>'); |
|
} |
|
} |
|
|
|
return pager.join(''); |
|
}() |
|
|
|
//下一页 |
|
,next: function(){ |
|
return config.next |
|
? '<a href="javascript:;" class="layui-laypage-next'+ (config.curr == config.pages ? (' ' + DISABLED) : '') +'" data-page="'+ (config.curr + 1) +'">'+ config.next +'</a>' |
|
: ''; |
|
}() |
|
|
|
//数据总数 |
|
,count: '<span class="layui-laypage-count">共 '+ config.count +' 条</span>' |
|
|
|
//每页条数 |
|
,limit: function(){ |
|
var options = ['<span class="layui-laypage-limits"><select lay-ignore>']; |
|
layui.each(config.limits, function(index, item){ |
|
options.push( |
|
'<option value="'+ item +'"' |
|
+(item === config.limit ? 'selected' : '') |
|
+'>'+ item +' 条/页</option>' |
|
); |
|
}); |
|
return options.join('') +'</select></span>'; |
|
}() |
|
|
|
//刷新当前页 |
|
,refresh: ['<a href="javascript:;" data-page="'+ config.curr +'" class="layui-laypage-refresh">' |
|
,'<i class="layui-icon layui-icon-refresh"></i>' |
|
,'</a>'].join('') |
|
|
|
//跳页区域 |
|
,skip: function(){ |
|
return ['<span class="layui-laypage-skip">到第' |
|
,'<input type="text" min="1" value="'+ config.curr +'" class="layui-input">' |
|
,'页<button type="button" class="layui-laypage-btn">确定</button>' |
|
,'</span>'].join(''); |
|
}() |
|
}; |
|
|
|
return ['<div class="layui-box layui-laypage layui-laypage-'+ (config.theme ? ( |
|
/^#/.test(config.theme) ? 'molv' : config.theme |
|
) : 'default') +'" id="layui-laypage-'+ config.index +'">' |
|
,function(){ |
|
var plate = []; |
|
layui.each(config.layout, function(index, item){ |
|
if(views[item]){ |
|
plate.push(views[item]) |
|
} |
|
}); |
|
return plate.join(''); |
|
}() |
|
,'</div>'].join(''); |
|
}; |
|
|
|
//跳页的回调 |
|
Class.prototype.jump = function(elem, isskip){ |
|
if(!elem) return; |
|
var that = this |
|
,config = that.config |
|
,childs = elem.children |
|
,btn = elem[tag]('button')[0] |
|
,input = elem[tag]('input')[0] |
|
,select = elem[tag]('select')[0] |
|
,skip = function(){ |
|
var curr = input.value.replace(/\s|\D/g, '')|0; |
|
if(curr){ |
|
config.curr = curr; |
|
that.render(); |
|
} |
|
}; |
|
|
|
if(isskip) return skip(); |
|
|
|
//页码 |
|
for(var i = 0, len = childs.length; i < len; i++){ |
|
if(childs[i].nodeName.toLowerCase() === 'a'){ |
|
laypage.on(childs[i], 'click', function(){ |
|
var curr = this.getAttribute('data-page')|0; |
|
if(curr < 1 || curr > config.pages) return; |
|
config.curr = curr; |
|
that.render(); |
|
}); |
|
} |
|
} |
|
|
|
//条数 |
|
if(select){ |
|
laypage.on(select, 'change', function(){ |
|
var value = this.value; |
|
if(config.curr*value > config.count){ |
|
config.curr = Math.ceil(config.count/value); |
|
} |
|
config.limit = value; |
|
that.render(); |
|
}); |
|
} |
|
|
|
//确定 |
|
if(btn){ |
|
laypage.on(btn, 'click', function(){ |
|
skip(); |
|
}); |
|
} |
|
}; |
|
|
|
//输入页数字控制 |
|
Class.prototype.skip = function(elem){ |
|
if(!elem) return; |
|
var that = this, input = elem[tag]('input')[0]; |
|
if(!input) return; |
|
laypage.on(input, 'keyup', function(e){ |
|
var value = this.value |
|
,keyCode = e.keyCode; |
|
if(/^(37|38|39|40)$/.test(keyCode)) return; |
|
if(/\D/.test(value)){ |
|
this.value = value.replace(/\D/, ''); |
|
} |
|
if(keyCode === 13){ |
|
that.jump(elem, true) |
|
} |
|
}); |
|
}; |
|
|
|
//渲染分页 |
|
Class.prototype.render = function(load){ |
|
var that = this |
|
,config = that.config |
|
,type = that.type() |
|
,view = that.view(); |
|
|
|
if(type === 2){ |
|
config.elem && (config.elem.innerHTML = view); |
|
} else if(type === 3){ |
|
config.elem.html(view); |
|
} else { |
|
if(doc[id](config.elem)){ |
|
doc[id](config.elem).innerHTML = view; |
|
} |
|
} |
|
|
|
config.jump && config.jump(config, load); |
|
|
|
var elem = doc[id]('layui-laypage-' + config.index); |
|
that.jump(elem); |
|
|
|
if(config.hash && !load){ |
|
location.hash = '!'+ config.hash +'='+ config.curr; |
|
} |
|
|
|
that.skip(elem); |
|
}; |
|
|
|
//外部接口 |
|
var laypage = { |
|
//分页渲染 |
|
render: function(options){ |
|
var o = new Class(options); |
|
return o.index; |
|
} |
|
,index: layui.laypage ? (layui.laypage.index + 10000) : 0 |
|
,on: function(elem, even, fn){ |
|
elem.attachEvent ? elem.attachEvent('on'+ even, function(e){ //for ie |
|
e.target = e.srcElement; |
|
fn.call(elem, e); |
|
}) : elem.addEventListener(even, fn, false); |
|
return this; |
|
} |
|
} |
|
|
|
exports(MOD_NAME, laypage); |
|
}); |