table.js 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285
  1. /**
  2. @Name:layui.table 表格操作
  3. @Author:贤心
  4. @License:MIT
  5. */
  6. layui.define(['laytpl', 'laypage', 'layer', 'form'], function(exports){
  7. "use strict";
  8. var $ = layui.$
  9. ,laytpl = layui.laytpl
  10. ,laypage = layui.laypage
  11. ,layer = layui.layer
  12. ,form = layui.form
  13. ,hint = layui.hint()
  14. ,device = layui.device()
  15. //外部接口
  16. ,table = {
  17. config: {
  18. checkName: 'LAY_CHECKED' //是否选中状态的字段名
  19. ,indexName: 'LAY_TABLE_INDEX' //下标索引名
  20. } //全局配置项
  21. ,cache: {} //数据缓存
  22. ,index: layui.table ? (layui.table.index + 10000) : 0
  23. //设置全局项
  24. ,set: function(options){
  25. var that = this;
  26. that.config = $.extend({}, that.config, options);
  27. return that;
  28. }
  29. //事件监听
  30. ,on: function(events, callback){
  31. return layui.onevent.call(this, MOD_NAME, events, callback);
  32. }
  33. }
  34. //操作当前实例
  35. ,thisTable = function(){
  36. var that = this
  37. ,options = that.config
  38. ,id = options.id;
  39. id && (thisTable.config[id] = options);
  40. return {
  41. reload: function(options){
  42. that.reload.call(that, options);
  43. }
  44. ,config: options
  45. }
  46. }
  47. //字符常量
  48. ,MOD_NAME = 'table', ELEM = '.layui-table', THIS = 'layui-this', SHOW = 'layui-show', HIDE = 'layui-hide', DISABLED = 'layui-disabled', NONE = 'layui-none'
  49. ,ELEM_VIEW = 'layui-table-view', ELEM_HEADER = '.layui-table-header', ELEM_BODY = '.layui-table-body', ELEM_MAIN = '.layui-table-main', ELEM_FIXED = '.layui-table-fixed', ELEM_FIXL = '.layui-table-fixed-l', ELEM_FIXR = '.layui-table-fixed-r', ELEM_TOOL = '.layui-table-tool', ELEM_PAGE = '.layui-table-page', ELEM_SORT = '.layui-table-sort', ELEM_EDIT = 'layui-table-edit', ELEM_HOVER = 'layui-table-hover'
  50. //thead区域模板
  51. ,TPL_HEADER = function(options){
  52. var rowCols = '{{#if(item2.colspan){}} colspan="{{item2.colspan}}"{{#} if(item2.rowspan){}} rowspan="{{item2.rowspan}}"{{#}}}';
  53. options = options || {};
  54. return ['<table cellspacing="0" cellpadding="0" border="0" class="layui-table" '
  55. ,'{{# if(d.data.skin){ }}lay-skin="{{d.data.skin}}"{{# } }} {{# if(d.data.size){ }}lay-size="{{d.data.size}}"{{# } }} {{# if(d.data.even){ }}lay-even{{# } }}>'
  56. ,'<thead>'
  57. ,'{{# layui.each(d.data.cols, function(i1, item1){ }}'
  58. ,'<tr>'
  59. ,'{{# layui.each(item1, function(i2, item2){ }}'
  60. ,'{{# if(item2.fixed && item2.fixed !== "right"){ left = true; } }}'
  61. ,'{{# if(item2.fixed === "right"){ right = true; } }}'
  62. ,function(){
  63. if(options.fixed && options.fixed !== 'right'){
  64. return '{{# if(item2.fixed && item2.fixed !== "right"){ }}';
  65. }
  66. if(options.fixed === 'right'){
  67. return '{{# if(item2.fixed === "right"){ }}';
  68. }
  69. return '';
  70. }()
  71. ,'<th data-field="{{ item2.field||i2 }}" {{# if(item2.minWidth){ }}data-minwidth="{{item2.minWidth}}"{{# } }} '+ rowCols +' {{# if(item2.unresize){ }}data-unresize="true"{{# } }}>'
  72. ,'<div class="layui-table-cell laytable-cell-'
  73. ,'{{# if(item2.colspan > 1){ }}'
  74. ,'group'
  75. ,'{{# } else { }}'
  76. ,'{{d.index}}-{{item2.field || i2}}'
  77. ,'{{# if(item2.type !== "normal"){ }}'
  78. ,' laytable-cell-{{ item2.type }}'
  79. ,'{{# } }}'
  80. ,'{{# } }}'
  81. ,'" {{#if(item2.align){}}align="{{item2.align}}"{{#}}}>'
  82. ,'{{# if(item2.type === "checkbox"){ }}' //复选框
  83. ,'<input type="checkbox" name="layTableCheckbox" lay-skin="primary" lay-filter="layTableAllChoose" {{# if(item2[d.data.checkName]){ }}checked{{# }; }}>'
  84. ,'{{# } else { }}'
  85. ,'<span>{{item2.title||""}}</span>'
  86. ,'{{# if(!(item2.colspan > 1) && item2.sort){ }}'
  87. ,'<span class="layui-table-sort layui-inline"><i class="layui-edge layui-table-sort-asc"></i><i class="layui-edge layui-table-sort-desc"></i></span>'
  88. ,'{{# } }}'
  89. ,'{{# } }}'
  90. ,'</div>'
  91. ,'</th>'
  92. ,(options.fixed ? '{{# }; }}' : '')
  93. ,'{{# }); }}'
  94. ,'</tr>'
  95. ,'{{# }); }}'
  96. ,'</thead>'
  97. ,'</table>'].join('');
  98. }
  99. //tbody区域模板
  100. ,TPL_BODY = ['<table cellspacing="0" cellpadding="0" border="0" class="layui-table" '
  101. ,'{{# if(d.data.skin){ }}lay-skin="{{d.data.skin}}"{{# } }} {{# if(d.data.size){ }}lay-size="{{d.data.size}}"{{# } }} {{# if(d.data.even){ }}lay-even{{# } }}>'
  102. ,'<tbody></tbody>'
  103. ,'</table>'].join('')
  104. //主模板
  105. ,TPL_MAIN = ['<div class="layui-form layui-border-box {{d.VIEW_CLASS}}" lay-filter="LAY-table-{{d.index}}" style="{{# if(d.data.width){ }}width:{{d.data.width}}px;{{# } }} {{# if(d.data.height){ }}height:{{d.data.height}}px;{{# } }}">'
  106. ,'{{# if(d.data.toolbar){ }}'
  107. ,'<div class="layui-table-tool"></div>'
  108. ,'{{# } }}'
  109. ,'<div class="layui-table-box">'
  110. ,'{{# var left, right; }}'
  111. ,'<div class="layui-table-header">'
  112. ,TPL_HEADER()
  113. ,'</div>'
  114. ,'<div class="layui-table-body layui-table-main">'
  115. ,TPL_BODY
  116. ,'</div>'
  117. ,'{{# if(left){ }}'
  118. ,'<div class="layui-table-fixed layui-table-fixed-l">'
  119. ,'<div class="layui-table-header">'
  120. ,TPL_HEADER({fixed: true})
  121. ,'</div>'
  122. ,'<div class="layui-table-body">'
  123. ,TPL_BODY
  124. ,'</div>'
  125. ,'</div>'
  126. ,'{{# }; }}'
  127. ,'{{# if(right){ }}'
  128. ,'<div class="layui-table-fixed layui-table-fixed-r">'
  129. ,'<div class="layui-table-header">'
  130. ,TPL_HEADER({fixed: 'right'})
  131. ,'<div class="layui-table-mend"></div>'
  132. ,'</div>'
  133. ,'<div class="layui-table-body">'
  134. ,TPL_BODY
  135. ,'</div>'
  136. ,'</div>'
  137. ,'{{# }; }}'
  138. ,'</div>'
  139. ,'{{# if(d.data.page){ }}'
  140. ,'<div class="layui-table-page">'
  141. ,'<div id="layui-table-page{{d.index}}"></div>'
  142. ,'</div>'
  143. ,'{{# } }}'
  144. ,'<style>'
  145. ,'{{# layui.each(d.data.cols, function(i1, item1){'
  146. ,'layui.each(item1, function(i2, item2){ }}'
  147. ,'.laytable-cell-{{d.index}}-{{item2.field||i2}}{ '
  148. ,'{{# if(item2.width){ }}'
  149. ,'width: {{item2.width}}px;'
  150. ,'{{# } }}'
  151. ,' }'
  152. ,'{{# });'
  153. ,'}); }}'
  154. ,'</style>'
  155. ,'</div>'].join('')
  156. ,_WIN = $(window)
  157. ,_DOC = $(document)
  158. //构造器
  159. ,Class = function(options){
  160. var that = this;
  161. that.index = ++table.index;
  162. that.config = $.extend({}, that.config, table.config, options);
  163. that.render();
  164. };
  165. //默认配置
  166. Class.prototype.config = {
  167. limit: 10 //每页显示的数量
  168. ,loading: true //请求数据时,是否显示loading
  169. ,cellMinWidth: 60 //所有单元格默认最小宽度
  170. ,text: {
  171. none: '无数据'
  172. }
  173. };
  174. //表格渲染
  175. Class.prototype.render = function(){
  176. var that = this
  177. ,options = that.config;
  178. options.elem = $(options.elem);
  179. options.where = options.where || {};
  180. options.id = options.id || options.elem.attr('id');
  181. //请求参数的自定义格式
  182. options.request = $.extend({
  183. pageName: 'page'
  184. ,limitName: 'limit'
  185. }, options.request)
  186. //响应数据的自定义格式
  187. options.response = $.extend({
  188. statusName: 'code'
  189. ,statusCode: 0
  190. ,msgName: 'msg'
  191. ,dataName: 'data'
  192. ,countName: 'count'
  193. }, options.response);
  194. //如果 page 传入 laypage 对象
  195. if(typeof options.page === 'object'){
  196. options.limit = options.page.limit || options.limit;
  197. options.limits = options.page.limits || options.limits;
  198. that.page = options.page.curr = options.page.curr || 1;
  199. delete options.page.elem;
  200. delete options.page.jump;
  201. }
  202. if(!options.elem[0]) return that;
  203. that.setArea(); //动态分配列宽高
  204. //开始插入替代元素
  205. var othis = options.elem
  206. ,hasRender = othis.next('.' + ELEM_VIEW)
  207. //主容器
  208. ,reElem = that.elem = $(laytpl(TPL_MAIN).render({
  209. VIEW_CLASS: ELEM_VIEW
  210. ,data: options
  211. ,index: that.index //索引
  212. }));
  213. options.index = that.index;
  214. //生成替代元素
  215. hasRender[0] && hasRender.remove(); //如果已经渲染,则Rerender
  216. othis.after(reElem);
  217. //各级容器
  218. that.layHeader = reElem.find(ELEM_HEADER);
  219. that.layMain = reElem.find(ELEM_MAIN);
  220. that.layBody = reElem.find(ELEM_BODY);
  221. that.layFixed = reElem.find(ELEM_FIXED);
  222. that.layFixLeft = reElem.find(ELEM_FIXL);
  223. that.layFixRight = reElem.find(ELEM_FIXR);
  224. that.layTool = reElem.find(ELEM_TOOL);
  225. that.layPage = reElem.find(ELEM_PAGE);
  226. that.layTool.html(
  227. laytpl($(options.toolbar).html()||'').render(options)
  228. );
  229. if(options.height) that.fullSize(); //设置body区域高度
  230. //如果多级表头,则填补表头高度
  231. if(options.cols.length > 1){
  232. var th = that.layFixed.find(ELEM_HEADER).find('th');
  233. th.height(that.layHeader.height() - 1 - parseFloat(th.css('padding-top')) - parseFloat(th.css('padding-bottom')));
  234. }
  235. //请求数据
  236. that.pullData(that.page);
  237. that.events();
  238. };
  239. //根据列类型,定制化参数
  240. Class.prototype.initOpts = function(item){
  241. var that = this,
  242. options = that.config
  243. ,initWidth = {
  244. checkbox: 48
  245. ,space: 15
  246. ,numbers: 40
  247. };
  248. //让 type 参数兼容旧版本
  249. if(item.checkbox) item.type = "checkbox";
  250. if(item.space) item.type = "space";
  251. if(!item.type) item.type = "normal";
  252. if(item.type !== "normal"){
  253. item.unresize = true;
  254. item.width = item.width || initWidth[item.type];
  255. }
  256. };
  257. //动态分配列宽高
  258. Class.prototype.setArea = function(){
  259. var that = this,
  260. options = that.config
  261. ,colNums = 0 //列个数
  262. ,autoColNums = 0 //自动列宽的列个数
  263. ,autoWidth = 0 //自动列分配的宽度
  264. ,countWidth = 0 //所有列总宽度和
  265. ,cntrWidth = options.width || function(){ //获取容器宽度
  266. //如果父元素宽度为0(一般为隐藏元素),则继续查找上层元素,直到找到真实宽度为止
  267. var getWidth = function(parent){
  268. var width, isNone;
  269. parent = parent || options.elem.parent()
  270. width = parent.width();
  271. try {
  272. isNone = parent.css('display') === 'none';
  273. } catch(e){}
  274. if(parent[0] && (!width || isNone)) return getWidth(parent.parent());
  275. return width;
  276. };
  277. return getWidth();
  278. }();
  279. //统计列个数
  280. that.eachCols(function(){
  281. colNums++;
  282. });
  283. //减去边框差
  284. cntrWidth = cntrWidth - function(){
  285. return (options.skin === 'line' || options.skin === 'nob') ? 2 : colNums + 1;
  286. }();
  287. //遍历所有列
  288. layui.each(options.cols, function(i1, item1){
  289. layui.each(item1, function(i2, item2){
  290. var width;
  291. if(!item2){
  292. item1.splice(i2, 1);
  293. return;
  294. }
  295. that.initOpts(item2);
  296. width = item2.width || 0;
  297. if(item2.colspan > 1) return;
  298. if(/\d+%$/.test(width)){
  299. item2.width = width = Math.floor((parseFloat(width) / 100) * cntrWidth);
  300. } else if(!width){ //列宽未填写
  301. item2.width = width = 0;
  302. autoColNums++;
  303. }
  304. countWidth = countWidth + width;
  305. });
  306. });
  307. that.autoColNums = autoColNums; //记录自动列数
  308. //如果未填充满,则将剩余宽度平分。否则,给未设定宽度的列赋值一个默认宽
  309. (cntrWidth > countWidth && autoColNums) && (
  310. autoWidth = (cntrWidth - countWidth) / autoColNums
  311. );
  312. layui.each(options.cols, function(i1, item1){
  313. layui.each(item1, function(i2, item2){
  314. var minWidth = item2.minWidth || options.cellMinWidth;
  315. if(item2.colspan > 1) return;
  316. if(item2.width === 0){
  317. item2.width = Math.floor(autoWidth >= minWidth ? autoWidth : minWidth); //不能低于设定的最小宽度
  318. }
  319. });
  320. });
  321. //高度铺满:full-差距值
  322. if(options.height && /^full-\d+$/.test(options.height)){
  323. that.fullHeightGap = options.height.split('-')[1];
  324. options.height = _WIN.height() - that.fullHeightGap;
  325. }
  326. };
  327. //表格重载
  328. Class.prototype.reload = function(options){
  329. var that = this;
  330. if(that.config.data && that.config.data.constructor === Array) delete that.config.data;
  331. that.config = $.extend({}, that.config, options);
  332. that.render();
  333. };
  334. //页码
  335. Class.prototype.page = 1;
  336. //获得数据
  337. Class.prototype.pullData = function(curr, loadIndex){
  338. var that = this
  339. ,options = that.config
  340. ,request = options.request
  341. ,response = options.response
  342. ,sort = function(){
  343. if(typeof options.initSort === 'object'){
  344. that.sort(options.initSort.field, options.initSort.type);
  345. }
  346. };
  347. that.startTime = new Date().getTime(); //渲染开始时间
  348. if(options.url){ //Ajax请求
  349. var params = {};
  350. params[request.pageName] = curr;
  351. params[request.limitName] = options.limit;
  352. $.ajax({
  353. type: options.method || 'get'
  354. ,url: options.url
  355. ,data: $.extend(params, options.where)
  356. ,dataType: 'json'
  357. ,success: function(res){
  358. if(res[response.statusName] != response.statusCode){
  359. that.renderForm();
  360. that.layMain.html('<div class="'+ NONE +'">'+ (res[response.msgName] || '返回的数据状态异常') +'</div>');
  361. } else {
  362. that.renderData(res, curr, res[response.countName]), sort();
  363. options.time = (new Date().getTime() - that.startTime) + ' ms'; //耗时(接口请求+视图渲染)
  364. }
  365. loadIndex && layer.close(loadIndex);
  366. typeof options.done === 'function' && options.done(res, curr, res[response.countName]);
  367. }
  368. ,error: function(e, m){
  369. that.layMain.html('<div class="'+ NONE +'">数据接口请求异常</div>');
  370. that.renderForm();
  371. loadIndex && layer.close(loadIndex);
  372. }
  373. });
  374. } else if(options.data && options.data.constructor === Array){ //已知数据
  375. var res = {}
  376. ,startLimit = curr*options.limit - options.limit
  377. res[response.dataName] = options.data.concat().splice(startLimit, options.limit);
  378. res[response.countName] = options.data.length;
  379. that.renderData(res, curr, options.data.length), sort();
  380. typeof options.done === 'function' && options.done(res, curr, res[response.countName]);
  381. }
  382. };
  383. //遍历表头
  384. Class.prototype.eachCols = function(callback){
  385. var cols = $.extend(true, [], this.config.cols)
  386. ,arrs = [], index = 0;
  387. //重新整理表头结构
  388. layui.each(cols, function(i1, item1){
  389. layui.each(item1, function(i2, item2){
  390. //如果是组合列,则捕获对应的子列
  391. if(item2.colspan > 1){
  392. var childIndex = 0;
  393. index++
  394. item2.CHILD_COLS = [];
  395. layui.each(cols[i1 + 1], function(i22, item22){
  396. if(item22.PARENT_COL || childIndex == item2.colspan) return;
  397. item22.PARENT_COL = index;
  398. item2.CHILD_COLS.push(item22);
  399. childIndex = childIndex + (item22.colspan > 1 ? item22.colspan : 1);
  400. });
  401. }
  402. if(item2.PARENT_COL) return; //如果是子列,则不进行追加,因为已经存储在父列中
  403. arrs.push(item2)
  404. });
  405. });
  406. //重新遍历列,如果有子列,则进入递归
  407. var eachArrs = function(obj){
  408. layui.each(obj || arrs, function(i, item){
  409. if(item.CHILD_COLS) return eachArrs(item.CHILD_COLS);
  410. callback(i, item);
  411. });
  412. };
  413. eachArrs();
  414. };
  415. //数据渲染
  416. Class.prototype.renderData = function(res, curr, count, sort){
  417. var that = this
  418. ,options = that.config
  419. ,data = res[options.response.dataName] || []
  420. ,trs = []
  421. ,trs_fixed = []
  422. ,trs_fixed_r = []
  423. //渲染视图
  424. ,render = function(){ //后续性能提升的重点
  425. if(!sort && that.sortKey){
  426. return that.sort(that.sortKey.field, that.sortKey.sort, true);
  427. }
  428. layui.each(data, function(i1, item1){
  429. var tds = [], tds_fixed = [], tds_fixed_r = []
  430. ,numbers = i1 + options.limit*(curr - 1) + 1; //序号
  431. if(item1.length === 0) return;
  432. if(!sort){
  433. item1[table.config.indexName] = i1;
  434. }
  435. that.eachCols(function(i3, item3){
  436. var field = item3.field || i3, content = item1[field]
  437. ,cell = that.getColElem(that.layHeader, field);
  438. if(content === undefined || content === null) content = '';
  439. if(item3.colspan > 1) return;
  440. //td内容
  441. var td = ['<td data-field="'+ field +'" '+ function(){
  442. var attr = [];
  443. if(item3.edit) attr.push('data-edit="'+ item3.edit +'"'); //是否允许单元格编辑
  444. if(item3.align) attr.push('align="'+ item3.align +'"'); //对齐方式
  445. if(item3.templet) attr.push('data-content="'+ content +'"'); //自定义模板
  446. if(item3.toolbar) attr.push('data-off="true"'); //自定义模板
  447. if(item3.event) attr.push('lay-event="'+ item3.event +'"'); //自定义事件
  448. if(item3.style) attr.push('style="'+ item3.style +'"'); //自定义样式
  449. if(item3.minWidth) attr.push('data-minwidth="'+ item3.minWidth +'"'); //单元格最小宽度
  450. return attr.join(' ');
  451. }() +'>'
  452. ,'<div class="layui-table-cell laytable-cell-'+ function(){ //返回对应的CSS类标识
  453. var str = (options.index + '-' + field);
  454. return item3.type === 'normal' ? str
  455. : (str + ' laytable-cell-' + item3.type);
  456. }() +'">' + function(){
  457. var tplData = $.extend(true, {
  458. LAY_INDEX: numbers
  459. }, item1);
  460. //渲染复选框列视图
  461. if(item3.type === 'checkbox'){
  462. return '<input type="checkbox" name="layTableCheckbox" lay-skin="primary" '+ function(){
  463. var checkName = table.config.checkName;
  464. //如果是全选
  465. if(item3[checkName]){
  466. item1[checkName] = item3[checkName];
  467. return item3[checkName] ? 'checked' : '';
  468. }
  469. return tplData[checkName] ? 'checked' : '';
  470. }() +'>';
  471. } else if(item3.type === 'numbers'){ //渲染序号
  472. return numbers;
  473. }
  474. //解析工具列模板
  475. if(item3.toolbar){
  476. return laytpl($(item3.toolbar).html()||'').render(tplData);
  477. }
  478. return item3.templet ? function(){
  479. return typeof item3.templet === 'function'
  480. ? item3.templet(tplData)
  481. : laytpl($(item3.templet).html() || String(content)).render(tplData)
  482. }() : content;
  483. }()
  484. ,'</div></td>'].join('');
  485. tds.push(td);
  486. if(item3.fixed && item3.fixed !== 'right') tds_fixed.push(td);
  487. if(item3.fixed === 'right') tds_fixed_r.push(td);
  488. });
  489. trs.push('<tr data-index="'+ i1 +'">'+ tds.join('') + '</tr>');
  490. trs_fixed.push('<tr data-index="'+ i1 +'">'+ tds_fixed.join('') + '</tr>');
  491. trs_fixed_r.push('<tr data-index="'+ i1 +'">'+ tds_fixed_r.join('') + '</tr>');
  492. });
  493. //if(data.length === 0) return;
  494. that.layBody.scrollTop(0);
  495. that.layMain.find('.'+ NONE).remove();
  496. that.layMain.find('tbody').html(trs.join(''));
  497. that.layFixLeft.find('tbody').html(trs_fixed.join(''));
  498. that.layFixRight.find('tbody').html(trs_fixed_r.join(''));
  499. that.renderForm();
  500. that.syncCheckAll();
  501. that.haveInit ? that.scrollPatch() : setTimeout(function(){
  502. that.scrollPatch();
  503. }, 50);
  504. that.haveInit = true;
  505. layer.close(that.tipsIndex);
  506. };
  507. that.key = options.id || options.index;
  508. table.cache[that.key] = data; //记录数据
  509. //显示隐藏分页栏
  510. that.layPage[data.length === 0 && curr == 1 ? 'addClass' : 'removeClass'](HIDE);
  511. //排序
  512. if(sort){
  513. return render();
  514. }
  515. if(data.length === 0){
  516. that.renderForm();
  517. that.layFixed.remove();
  518. that.layMain.find('tbody').html('');
  519. that.layMain.find('.'+ NONE).remove();
  520. return that.layMain.append('<div class="'+ NONE +'">'+ options.text.none +'</div>');
  521. }
  522. render();
  523. //同步分页状态
  524. if(options.page){
  525. options.page = $.extend({
  526. elem: 'layui-table-page' + options.index
  527. ,count: count
  528. ,limit: options.limit
  529. ,limits: options.limits || [10,20,30,40,50,60,70,80,90]
  530. ,groups: 3
  531. ,layout: ['prev', 'page', 'next', 'skip', 'count', 'limit']
  532. ,prev: '<i class="layui-icon">&#xe603;</i>'
  533. ,next: '<i class="layui-icon">&#xe602;</i>'
  534. ,jump: function(obj, first){
  535. if(!first){
  536. //分页本身并非需要做以下更新,下面参数的同步,主要是因为其它处理统一用到了它们
  537. //而并非用的是 options.page 中的参数(以确保分页未开启的情况仍能正常使用)
  538. that.page = obj.curr; //更新页码
  539. options.limit = obj.limit; //更新每页条数
  540. that.pullData(obj.curr, that.loading());
  541. }
  542. }
  543. }, options.page);
  544. options.page.count = count; //更新总条数
  545. laypage.render(options.page);
  546. }
  547. };
  548. //找到对应的列元素
  549. Class.prototype.getColElem = function(parent, field){
  550. var that = this
  551. ,options = that.config;
  552. return parent.eq(0).find('.laytable-cell-'+ (options.index + '-' + field) + ':eq(0)');
  553. };
  554. //渲染表单
  555. Class.prototype.renderForm = function(type){
  556. form.render(type, 'LAY-table-'+ this.index);
  557. }
  558. //数据排序
  559. Class.prototype.sort = function(th, type, pull, formEvent){
  560. var that = this
  561. ,field
  562. ,res = {}
  563. ,options = that.config
  564. ,filter = options.elem.attr('lay-filter')
  565. ,data = table.cache[that.key], thisData;
  566. //字段匹配
  567. if(typeof th === 'string'){
  568. that.layHeader.find('th').each(function(i, item){
  569. var othis = $(this)
  570. ,_field = othis.data('field');
  571. if(_field === th){
  572. th = othis;
  573. field = _field;
  574. return false;
  575. }
  576. });
  577. }
  578. try {
  579. var field = field || th.data('field');
  580. //如果欲执行的排序已在状态中,则不执行渲染
  581. if(that.sortKey && !pull){
  582. if(field === that.sortKey.field && type === that.sortKey.sort){
  583. return;
  584. }
  585. }
  586. var elemSort = that.layHeader.find('th .laytable-cell-'+ options.index +'-'+ field).find(ELEM_SORT);
  587. that.layHeader.find('th').find(ELEM_SORT).removeAttr('lay-sort'); //清除其它标题排序状态
  588. elemSort.attr('lay-sort', type || null);
  589. that.layFixed.find('th')
  590. } catch(e){
  591. return hint.error('Table modules: Did not match to field');
  592. }
  593. //记录排序索引和类型
  594. that.sortKey = {
  595. field: field
  596. ,sort: type
  597. };
  598. if(type === 'asc'){ //升序
  599. thisData = layui.sort(data, field);
  600. } else if(type === 'desc'){ //降序
  601. thisData = layui.sort(data, field, true);
  602. } else { //清除排序
  603. thisData = layui.sort(data, table.config.indexName);
  604. delete that.sortKey;
  605. }
  606. res[options.response.dataName] = thisData;
  607. that.renderData(res, that.page, that.count, true);
  608. if(formEvent){
  609. layui.event.call(th, MOD_NAME, 'sort('+ filter +')', {
  610. field: field
  611. ,type: type
  612. });
  613. }
  614. };
  615. //请求loading
  616. Class.prototype.loading = function(){
  617. var that = this
  618. ,options = that.config;
  619. if(options.loading && options.url){
  620. return layer.msg('数据请求中', {
  621. icon: 16
  622. ,offset: [
  623. that.elem.offset().top + that.elem.height()/2 - 35 - _WIN.scrollTop() + 'px'
  624. ,that.elem.offset().left + that.elem.width()/2 - 90 - _WIN.scrollLeft() + 'px'
  625. ]
  626. ,time: -1
  627. ,anim: -1
  628. ,fixed: false
  629. });
  630. }
  631. };
  632. //同步选中值状态
  633. Class.prototype.setCheckData = function(index, checked){
  634. var that = this
  635. ,options = that.config
  636. ,thisData = table.cache[that.key];
  637. if(!thisData[index]) return;
  638. if(thisData[index].constructor === Array) return;
  639. thisData[index][options.checkName] = checked;
  640. };
  641. //同步全选按钮状态
  642. Class.prototype.syncCheckAll = function(){
  643. var that = this
  644. ,options = that.config
  645. ,checkAllElem = that.layHeader.find('input[name="layTableCheckbox"]')
  646. ,syncColsCheck = function(checked){
  647. that.eachCols(function(i, item){
  648. if(item.type === 'checkbox'){
  649. item[options.checkName] = checked;
  650. }
  651. });
  652. return checked;
  653. };
  654. if(!checkAllElem[0]) return;
  655. if(table.checkStatus(that.key).isAll){
  656. if(!checkAllElem[0].checked){
  657. checkAllElem.prop('checked', true);
  658. that.renderForm('checkbox');
  659. }
  660. syncColsCheck(true);
  661. } else {
  662. if(checkAllElem[0].checked){
  663. checkAllElem.prop('checked', false);
  664. that.renderForm('checkbox');
  665. }
  666. syncColsCheck(false);
  667. }
  668. };
  669. //获取cssRule
  670. Class.prototype.getCssRule = function(field, callback){
  671. var that = this
  672. ,style = that.elem.find('style')[0]
  673. ,sheet = style.sheet || style.styleSheet || {}
  674. ,rules = sheet.cssRules || sheet.rules;
  675. layui.each(rules, function(i, item){
  676. if(item.selectorText === ('.laytable-cell-'+ that.index +'-'+ field)){
  677. return callback(item), true;
  678. }
  679. });
  680. };
  681. //铺满表格主体高度
  682. Class.prototype.fullSize = function(){
  683. var that = this
  684. ,options = that.config
  685. ,height = options.height, bodyHeight;
  686. if(that.fullHeightGap){
  687. height = _WIN.height() - that.fullHeightGap;
  688. if(height < 135) height = 135;
  689. that.elem.css('height', height);
  690. }
  691. //tbody区域高度
  692. bodyHeight = parseFloat(height) - parseFloat(that.layHeader.height()) - 1;
  693. if(options.toolbar){
  694. bodyHeight = bodyHeight - that.layTool.outerHeight();
  695. }
  696. if(options.page){
  697. bodyHeight = bodyHeight - that.layPage.outerHeight() - 1;
  698. }
  699. that.layMain.css('height', bodyHeight);
  700. };
  701. //获取滚动条宽度
  702. Class.prototype.getScrollWidth = function(elem){
  703. var width = 0;
  704. if(elem){
  705. width = elem.offsetWidth - elem.clientWidth;
  706. } else {
  707. elem = document.createElement('div');
  708. elem.style.width = '100px';
  709. elem.style.height = '100px';
  710. elem.style.overflowY = 'scroll';
  711. document.body.appendChild(elem);
  712. width = elem.offsetWidth - elem.clientWidth;
  713. document.body.removeChild(elem);
  714. }
  715. return width;
  716. };
  717. //滚动条补丁
  718. Class.prototype.scrollPatch = function(){
  719. var that = this
  720. ,layMainTable = that.layMain.children('table')
  721. ,scollWidth = that.layMain.width() - that.layMain.prop('clientWidth') //纵向滚动条宽度
  722. ,scollHeight = that.layMain.height() - that.layMain.prop('clientHeight') //横向滚动条高度
  723. ,getScrollWidth = that.getScrollWidth(that.layMain[0]) //获取主容器滚动条宽度,如果有的话
  724. ,outWidth = layMainTable.outerWidth() - that.layMain.width(); //表格内容器的超出宽度
  725. //如果存在自动列宽,则要保证绝对填充满,并且不能出现横向滚动条
  726. if(that.autoColNums && outWidth < 5 && !that.scrollPatchWStatus){
  727. var th = that.layHeader.eq(0).find('thead th:last-child')
  728. ,field = th.data('field');
  729. that.getCssRule(field, function(item){
  730. var width = item.style.width || th.outerWidth();
  731. item.style.width = (parseFloat(width) - getScrollWidth - outWidth) + 'px';
  732. //二次校验,如果仍然出现横向滚动条
  733. if(that.layMain.height() - that.layMain.prop('clientHeight') > 0){
  734. item.style.width = parseFloat(item.style.width) - 1 + 'px';
  735. }
  736. that.scrollPatchWStatus = true;
  737. });
  738. }
  739. if(scollWidth && scollHeight){
  740. if(!that.elem.find('.layui-table-patch')[0]){
  741. var patchElem = $('<th class="layui-table-patch"><div class="layui-table-cell"></div></th>'); //补丁元素
  742. patchElem.find('div').css({
  743. width: scollWidth
  744. });
  745. that.layHeader.eq(0).find('thead tr').append(patchElem)
  746. }
  747. } else {
  748. that.layHeader.eq(0).find('.layui-table-patch').remove();
  749. }
  750. //固定列区域高度
  751. var mainHeight = that.layMain.height()
  752. ,fixHeight = mainHeight - scollHeight;
  753. that.layFixed.find(ELEM_BODY).css('height', layMainTable.height() > fixHeight ? fixHeight : 'auto');
  754. //表格宽度小于容器宽度时,隐藏固定列
  755. that.layFixRight[outWidth > 0 ? 'removeClass' : 'addClass'](HIDE);
  756. //操作栏
  757. that.layFixRight.css('right', scollWidth - 1);
  758. };
  759. //事件处理
  760. Class.prototype.events = function(){
  761. var that = this
  762. ,options = that.config
  763. ,_BODY = $('body')
  764. ,dict = {}
  765. ,th = that.layHeader.find('th')
  766. ,resizing
  767. ,ELEM_CELL = '.layui-table-cell'
  768. ,filter = options.elem.attr('lay-filter');
  769. //拖拽调整宽度
  770. th.on('mousemove', function(e){
  771. var othis = $(this)
  772. ,oLeft = othis.offset().left
  773. ,pLeft = e.clientX - oLeft;
  774. if(othis.attr('colspan') > 1 || othis.data('unresize') || dict.resizeStart){
  775. return;
  776. }
  777. dict.allowResize = othis.width() - pLeft <= 10; //是否处于拖拽允许区域
  778. _BODY.css('cursor', (dict.allowResize ? 'col-resize' : ''));
  779. }).on('mouseleave', function(){
  780. var othis = $(this);
  781. if(dict.resizeStart) return;
  782. _BODY.css('cursor', '');
  783. }).on('mousedown', function(e){
  784. var othis = $(this);
  785. if(dict.allowResize){
  786. var field = othis.data('field');
  787. e.preventDefault();
  788. dict.resizeStart = true; //开始拖拽
  789. dict.offset = [e.clientX, e.clientY]; //记录初始坐标
  790. that.getCssRule(field, function(item){
  791. var width = item.style.width || othis.outerWidth();
  792. dict.rule = item;
  793. dict.ruleWidth = parseFloat(width);
  794. dict.minWidth = othis.data('minwidth') || options.cellMinWidth;
  795. });
  796. }
  797. });
  798. //拖拽中
  799. _DOC.on('mousemove', function(e){
  800. if(dict.resizeStart){
  801. e.preventDefault();
  802. if(dict.rule){
  803. var setWidth = dict.ruleWidth + e.clientX - dict.offset[0];
  804. if(setWidth < dict.minWidth) setWidth = dict.minWidth;
  805. dict.rule.style.width = setWidth + 'px';
  806. layer.close(that.tipsIndex);
  807. }
  808. resizing = 1
  809. }
  810. }).on('mouseup', function(e){
  811. if(dict.resizeStart){
  812. dict = {};
  813. _BODY.css('cursor', '');
  814. that.scrollPatch();
  815. }
  816. if(resizing === 2){
  817. resizing = null;
  818. }
  819. });
  820. //排序
  821. th.on('click', function(){
  822. var othis = $(this)
  823. ,elemSort = othis.find(ELEM_SORT)
  824. ,nowType = elemSort.attr('lay-sort')
  825. ,type;
  826. if(!elemSort[0] || resizing === 1) return resizing = 2;
  827. if(nowType === 'asc'){
  828. type = 'desc';
  829. } else if(nowType === 'desc'){
  830. type = null;
  831. } else {
  832. type = 'asc';
  833. }
  834. that.sort(othis, type, null, true);
  835. }).find(ELEM_SORT+' .layui-edge ').on('click', function(e){
  836. var othis = $(this)
  837. ,index = othis.index()
  838. ,field = othis.parents('th').eq(0).data('field')
  839. layui.stope(e);
  840. if(index === 0){
  841. that.sort(field, 'asc', null, true);
  842. } else {
  843. that.sort(field, 'desc', null, true);
  844. }
  845. });
  846. //复选框选择
  847. that.elem.on('click', 'input[name="layTableCheckbox"]+', function(){
  848. var checkbox = $(this).prev()
  849. ,childs = that.layBody.find('input[name="layTableCheckbox"]')
  850. ,index = checkbox.parents('tr').eq(0).data('index')
  851. ,checked = checkbox[0].checked
  852. ,isAll = checkbox.attr('lay-filter') === 'layTableAllChoose';
  853. //全选
  854. if(isAll){
  855. childs.each(function(i, item){
  856. item.checked = checked;
  857. that.setCheckData(i, checked);
  858. });
  859. that.syncCheckAll();
  860. that.renderForm('checkbox');
  861. } else {
  862. that.setCheckData(index, checked);
  863. that.syncCheckAll();
  864. }
  865. layui.event.call(this, MOD_NAME, 'checkbox('+ filter +')', {
  866. checked: checked
  867. ,data: table.cache[that.key] ? (table.cache[that.key][index] || {}) : {}
  868. ,type: isAll ? 'all' : 'one'
  869. });
  870. });
  871. //行事件
  872. that.layBody.on('mouseenter', 'tr', function(){
  873. var othis = $(this)
  874. ,index = othis.index();
  875. that.layBody.find('tr:eq('+ index +')').addClass(ELEM_HOVER)
  876. }).on('mouseleave', 'tr', function(){
  877. var othis = $(this)
  878. ,index = othis.index();
  879. that.layBody.find('tr:eq('+ index +')').removeClass(ELEM_HOVER)
  880. });
  881. //单元格编辑
  882. that.layBody.on('change', '.'+ELEM_EDIT, function(){
  883. var othis = $(this)
  884. ,value = this.value
  885. ,field = othis.parent().data('field')
  886. ,index = othis.parents('tr').eq(0).data('index')
  887. ,data = table.cache[that.key][index];
  888. data[field] = value; //更新缓存中的值
  889. layui.event.call(this, MOD_NAME, 'edit('+ filter +')', {
  890. value: value
  891. ,data: data
  892. ,field: field
  893. });
  894. }).on('blur', '.'+ELEM_EDIT, function(){
  895. var templet
  896. ,othis = $(this)
  897. ,field = othis.parent().data('field')
  898. ,index = othis.parents('tr').eq(0).data('index')
  899. ,data = table.cache[that.key][index];
  900. that.eachCols(function(i, item){
  901. if(item.field == field && item.templet){
  902. templet = item.templet;
  903. }
  904. });
  905. othis.siblings(ELEM_CELL).html(
  906. templet ? laytpl($(templet).html() || this.value).render(data) : this.value
  907. );
  908. othis.parent().data('content', this.value);
  909. othis.remove();
  910. });
  911. //单元格事件
  912. that.layBody.on('click', 'td', function(){
  913. var othis = $(this)
  914. ,field = othis.data('field')
  915. ,editType = othis.data('edit')
  916. ,elemCell = othis.children(ELEM_CELL);
  917. layer.close(that.tipsIndex);
  918. if(othis.data('off')) return;
  919. //显示编辑表单
  920. if(editType){
  921. if(editType === 'select') { //选择框
  922. //var select = $('<select class="'+ ELEM_EDIT +'" lay-ignore><option></option></select>');
  923. //othis.find('.'+ELEM_EDIT)[0] || othis.append(select);
  924. } else { //输入框
  925. var input = $('<input class="layui-input '+ ELEM_EDIT +'">');
  926. input[0].value = othis.data('content') || elemCell.text();
  927. othis.find('.'+ELEM_EDIT)[0] || othis.append(input);
  928. input.focus();
  929. }
  930. return;
  931. }
  932. //如果出现省略,则可查看更多
  933. if(elemCell.find('.layui-form-switch,.layui-form-checkbox')[0]) return; //限制不出现更多(暂时)
  934. if(Math.round(elemCell.prop('scrollWidth')) > Math.round(elemCell.outerWidth())){
  935. that.tipsIndex = layer.tips([
  936. '<div class="layui-table-tips-main" style="margin-top: -'+ (elemCell.height() + 16) +'px;'+ function(){
  937. if(options.size === 'sm'){
  938. return 'padding: 4px 15px; font-size: 12px;';
  939. }
  940. if(options.size === 'lg'){
  941. return 'padding: 14px 15px;';
  942. }
  943. return '';
  944. }() +'">'
  945. ,elemCell.html()
  946. ,'</div>'
  947. ,'<i class="layui-icon layui-table-tips-c">&#x1006;</i>'
  948. ].join(''), elemCell[0], {
  949. tips: [3, '']
  950. ,time: -1
  951. ,anim: -1
  952. ,maxWidth: (device.ios || device.android) ? 300 : 600
  953. ,isOutAnim: false
  954. ,skin: 'layui-table-tips'
  955. ,success: function(layero, index){
  956. layero.find('.layui-table-tips-c').on('click', function(){
  957. layer.close(index);
  958. });
  959. }
  960. });
  961. }
  962. });
  963. //工具条操作事件
  964. that.layBody.on('click', '*[lay-event]', function(){
  965. var othis = $(this)
  966. ,index = othis.parents('tr').eq(0).data('index')
  967. ,tr = that.layBody.find('tr[data-index="'+ index +'"]')
  968. ,ELEM_CLICK = 'layui-table-click'
  969. ,data = table.cache[that.key][index];
  970. layui.event.call(this, MOD_NAME, 'tool('+ filter +')', {
  971. data: table.clearCacheKey(data)
  972. ,event: othis.attr('lay-event')
  973. ,tr: tr
  974. ,del: function(){
  975. table.cache[that.key][index] = [];
  976. tr.remove();
  977. that.scrollPatch();
  978. }
  979. ,update: function(fields){
  980. fields = fields || {};
  981. layui.each(fields, function(key, value){
  982. if(key in data){
  983. var templet, td = tr.children('td[data-field="'+ key +'"]');
  984. data[key] = value;
  985. that.eachCols(function(i, item2){
  986. if(item2.field == key && item2.templet){
  987. templet = item2.templet;
  988. }
  989. });
  990. td.children(ELEM_CELL).html(
  991. templet ? laytpl($(templet).html() || value).render(data) : value
  992. );
  993. td.data('content', value);
  994. }
  995. });
  996. }
  997. });
  998. tr.addClass(ELEM_CLICK).siblings('tr').removeClass(ELEM_CLICK);
  999. });
  1000. //同步滚动条
  1001. that.layMain.on('scroll', function(){
  1002. var othis = $(this)
  1003. ,scrollLeft = othis.scrollLeft()
  1004. ,scrollTop = othis.scrollTop();
  1005. that.layHeader.scrollLeft(scrollLeft);
  1006. that.layFixed.find(ELEM_BODY).scrollTop(scrollTop);
  1007. layer.close(that.tipsIndex);
  1008. });
  1009. _WIN.on('resize', function(){ //自适应
  1010. that.fullSize();
  1011. that.scrollPatch();
  1012. });
  1013. };
  1014. //初始化
  1015. table.init = function(filter, settings){
  1016. settings = settings || {};
  1017. var that = this
  1018. ,elemTable = filter ? $('table[lay-filter="'+ filter +'"]') : $(ELEM + '[lay-data]')
  1019. ,errorTips = 'Table element property lay-data configuration item has a syntax error: ';
  1020. //遍历数据表格
  1021. elemTable.each(function(){
  1022. var othis = $(this), tableData = othis.attr('lay-data');
  1023. try{
  1024. tableData = new Function('return '+ tableData)();
  1025. } catch(e){
  1026. hint.error(errorTips + tableData)
  1027. }
  1028. var cols = [], options = $.extend({
  1029. elem: this
  1030. ,cols: []
  1031. ,data: []
  1032. ,skin: othis.attr('lay-skin') //风格
  1033. ,size: othis.attr('lay-size') //尺寸
  1034. ,even: typeof othis.attr('lay-even') === 'string' //偶数行背景
  1035. }, table.config, settings, tableData);
  1036. filter && othis.hide();
  1037. //获取表头数据
  1038. othis.find('thead>tr').each(function(i){
  1039. options.cols[i] = [];
  1040. $(this).children().each(function(ii){
  1041. var th = $(this), itemData = th.attr('lay-data');
  1042. try{
  1043. itemData = new Function('return '+ itemData)();
  1044. } catch(e){
  1045. return hint.error(errorTips + itemData)
  1046. }
  1047. var row = $.extend({
  1048. title: th.text()
  1049. ,colspan: th.attr('colspan') || 0 //列单元格
  1050. ,rowspan: th.attr('rowspan') || 0 //行单元格
  1051. }, itemData);
  1052. if(row.colspan < 2) cols.push(row);
  1053. options.cols[i].push(row);
  1054. });
  1055. });
  1056. //获取表体数据
  1057. othis.find('tbody>tr').each(function(i1){
  1058. var tr = $(this), row = {};
  1059. //如果定义了字段名
  1060. tr.children('td').each(function(i2, item2){
  1061. var td = $(this)
  1062. ,field = td.data('field');
  1063. if(field){
  1064. return row[field] = td.html();
  1065. }
  1066. });
  1067. //如果未定义字段名
  1068. layui.each(cols, function(i3, item3){
  1069. var td = tr.children('td').eq(i3);
  1070. row[item3.field] = td.html();
  1071. });
  1072. options.data[i1] = row;
  1073. });
  1074. table.render(options);
  1075. });
  1076. return that;
  1077. };
  1078. //表格选中状态
  1079. table.checkStatus = function(id){
  1080. var nums = 0
  1081. ,invalidNum = 0
  1082. ,arr = []
  1083. ,data = table.cache[id] || [];
  1084. //计算全选个数
  1085. layui.each(data, function(i, item){
  1086. if(item.constructor === Array){
  1087. invalidNum++; //无效数据,或已删除的
  1088. return;
  1089. }
  1090. if(item[table.config.checkName]){
  1091. nums++;
  1092. arr.push(table.clearCacheKey(item));
  1093. }
  1094. });
  1095. return {
  1096. data: arr //选中的数据
  1097. ,isAll: data.length ? (nums === (data.length - invalidNum)) : false //是否全选
  1098. };
  1099. };
  1100. //表格重载
  1101. thisTable.config = {};
  1102. table.reload = function(id, options){
  1103. var config = thisTable.config[id];
  1104. options = options || {};
  1105. if(!config) return hint.error('The ID option was not found in the table instance');
  1106. if(options.data && options.data.constructor === Array) delete config.data;
  1107. return table.render($.extend(true, {}, config, options));
  1108. };
  1109. //核心入口
  1110. table.render = function(options){
  1111. var inst = new Class(options);
  1112. return thisTable.call(inst);
  1113. };
  1114. //清除临时Key
  1115. table.clearCacheKey = function(data){
  1116. data = $.extend({}, data);
  1117. delete data[table.config.checkName];
  1118. delete data[table.config.indexName];
  1119. return data;
  1120. };
  1121. //自动完成渲染
  1122. table.init();
  1123. exports(MOD_NAME, table);
  1124. });