min-datatable.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508
  1. // datatable
  2. // 描述:根据配置信息,生成数据表,加上表头排序,表脚分页等信息,可以通过$("表单对象").datatable()进行刷新
  3. // 参数:
  4. // options[map]:
  5. // url[string]:请求url
  6. // data[map]:请求数据
  7. // page[string]:默认分页页码,会上送到服务器,若该值为null,表示不显示分页信息
  8. // limit[string]:默认每页显示条数,会上送到服务器
  9. // header[array]:表头信息
  10. // code[string]:列编码,会将所在列的每一个th或td的code属性设置为该编码,可以用于数据定位
  11. // name[string]:列名称,会显示在表头
  12. // width[string]:列宽
  13. // title[string]:标题
  14. // complete[function]:表格生成后,调用的方法,用于处理一些表格生成后的工作,比方说为列表添加操作信息和点击事件等
  15. // data[array]:列表数据
  16. // result[map]:服务器返回的数据
  17. // error[function]:操作失败后调用的方法
  18. // result[map]:服务器返回的数据
  19. // sequence[string]:显示序号
  20. // select[string]:显示复选框
  21. // 返回:无
  22. // 示例:
  23. // 代码:
  24. // $("#datatable").datatable({
  25. // url : "UserManageAction.userQuery.do",
  26. // data : {
  27. // page : 1,
  28. // limit : 10
  29. // },
  30. // select : "select",
  31. // sequence : "sequence",
  32. // header : [ {
  33. // code : "logonname",
  34. // name : "登录名"
  35. // }, {
  36. // code : "name",
  37. // name : "姓名"
  38. // }, {
  39. // code : "rolename",
  40. // name : "角色"
  41. // }, {
  42. // code : "branchname",
  43. // name : "所属机构"
  44. // }, {
  45. // code : "createdate",
  46. // name : "创建日期"
  47. // }, {
  48. // code : "lastlogon",
  49. // name : "最后登录日期"
  50. // }, {
  51. // code : "sttdesc",
  52. // name : "状态"
  53. // }, {
  54. // code : "execute",
  55. // name : "操作",
  56. // width : 350
  57. // } ],
  58. // complete : function(data) {
  59. // $("#datatable").find("td[code='execute']").append("<a execute='view' href='#'>查看</a> ");
  60. // $("#datatable").find("td[code='execute']").find("a[execute='view']").click(function() {
  61. // alert($(this).parents("tr").val());
  62. // });
  63. // }
  64. // });
  65. // ...
  66. // <div id="datatable">
  67. // <table>
  68. // </table>
  69. // </div>
  70. // 结果:发送数据到UserManageAction.userQuery.do,根据返回数据生成一个表格,并加上查看操作,以及序号和多选列
  71. $.widget("ui.datatable", {
  72. input : [],
  73. data : {
  74. page : null,
  75. limit : 10 // 注意,若action不接受limit参数,则双方应当约定每页记录数或者起始页数必须为1,否则无法正确计算offset
  76. },
  77. result : {},
  78. options : {
  79. url : null,
  80. data : {},
  81. header : null,
  82. maxRows : null,
  83. sort : null,
  84. order : 1,
  85. pageField : "page",
  86. limitField : "limit",
  87. dataField : "MINQueryResult",
  88. pagingField : "MINPaging",
  89. title : null,
  90. complete : null,
  91. error : null,
  92. sequence : null,
  93. select : null,
  94. sort : null,
  95. style : function() {
  96. },
  97. paging : function(handler, foot, cur, start, limit, max, first, last, prev, next) {
  98. // foot.append("<div page='true' align='right' >起始记录:" + start + " 每页记录数:" +
  99. // limit + " 记录总数:" + max + " 首页:" + first + " 上一页:" + prev + " 当前页:" + cur
  100. // + " 下一页:" + next + " 尾页:" + last + " <a href='#' page='" + first + "'
  101. // >首页</a> <a href='#' page='" + prev + "'>上一页</a> <a href='#' page='" +
  102. // next + "'>下一页</a> <a href='#' page='" + last + "'>尾页</a> <select
  103. // page></select> 每页显示<select limit></select></div>");
  104. if (max <= limit) {
  105. return;
  106. }
  107. var p="";
  108. var shu=(last-last%10)/10;
  109. if(shu>3){
  110. shu=3;
  111. }
  112. var flag=7+shu;
  113. if(last>=flag){
  114. if(cur<5+shu){
  115. for ( var i = first; i <flag; i++) {
  116. if(i==cur){
  117. p=p+"&nbsp;&nbsp;"+i+"&nbsp;";
  118. }else{
  119. p=p+"&nbsp;<a page='" + i + "' class='pageCount'>"+i+"</a>";
  120. }
  121. }
  122. p=p+"&nbsp;<a page='" + last + "'>..."+last+"</a>";
  123. }else if(cur>=(5+shu) && cur<(last-3)){
  124. p=p+"&nbsp;<a page='" + first + "' class='pageCount'>"+first+"...</a>";
  125. if(cur+2+shu<last-1){
  126. for ( var i = cur-2-(shu); i <=cur+2+shu; i++) {
  127. if(i==cur){
  128. p=p+"&nbsp;&nbsp;"+i+"&nbsp;";
  129. }else{
  130. p=p+"&nbsp;<a page='" + i + "' class='pageCount'>"+i+"</a>";
  131. }
  132. }
  133. p=p+"&nbsp;<a page='" + last + "' class='pageCount'>..."+last+"</a>";
  134. }else{
  135. for ( var i = cur-2-(shu); i <=last; i++) {
  136. if(i==cur){
  137. p=p+"&nbsp;&nbsp;"+i+"&nbsp;";
  138. }else{
  139. p=p+"&nbsp;<a page='" + i + "' class='pageCount'>"+i+"</a>";
  140. }
  141. }
  142. }
  143. }else if(cur<=last && cur>=(last-3)){
  144. p=p+"&nbsp;<a page='" + first + "'>"+first+"...</a>";
  145. for ( var i = last-5; i <=last; i++) {
  146. if(i==cur){
  147. p=p+"&nbsp;&nbsp;"+i+"&nbsp;";
  148. }else{
  149. p=p+"&nbsp;<a page='" + i + "' class='pageCount'>"+i+"</a>";
  150. }
  151. }
  152. }
  153. }else{
  154. for ( var i = first; i <= last; i++) {
  155. if(i==cur){
  156. p=p+"&nbsp;&nbsp;"+i+"&nbsp;";
  157. }else{
  158. p=p+"&nbsp;<a page='" + i + "' class='pageCount'>"+i+"</a>";
  159. }
  160. }
  161. }
  162. var head="&nbsp;&nbsp;<a page='" + prev + "' class='pageCount'> 上一页 </a>&nbsp;&nbsp;";
  163. var end="&nbsp;&nbsp;<a page='" + next + "' class='pageCount'> 下一页 </a>&nbsp;&nbsp;";
  164. var zong=head+p+end;
  165. if(cur=="1"){
  166. zong=p+end;
  167. }
  168. if(cur==last){
  169. zong=head+p;
  170. }
  171. var maxRow=start+limit-1;
  172. if(maxRow>max){
  173. maxRow=max;
  174. }
  175. foot.append("<div page='true' align='right' class='pageDiv'>本页记录第:<font color='red'>" + start + "</font>-<font color='red'>" + maxRow + "</font> 每页记录数:<font color='red'>" + limit + "</font> 记录总数:<font color='red'>" + max + "</font> "+zong+"&nbsp;<input type='text' id='go_int' size='2'/><a href='#' id='go_a'><img alt='GO' src='images/go.png' width='30px' height='26px'/></a>&nbsp;</div>");
  176. foot.find("div[page='true']").find("a[page]").click(function() {
  177. handler.options.data.limit = limit;
  178. handler.options.data.page = $(this).attr("page");
  179. if (Math.floor(max / handler.options.data.limit) + 1 < handler.options.data.page)
  180. handler.options.data.page = 1;
  181. handler._init();
  182. });
  183. //选页
  184. foot.find("#go_a").click(function() {
  185. var page=foot.find("#go_int").val();
  186. if(page!=""){
  187. var reg = /^[0-9]+$/;
  188. if(!reg.exec(page)){
  189. foot.find("#go_int").val("");
  190. $.hints({
  191. strong : "错误",
  192. error : [ "请输入有效数字" ]
  193. });
  194. return false ;
  195. }
  196. if(page<1){
  197. page =1;
  198. }
  199. if(page>last){
  200. page =last;
  201. }
  202. handler.options.data.limit = limit;
  203. handler.options.data.page = page;
  204. if (Math.floor(max / handler.options.data.limit) + 1 < handler.options.data.page)
  205. handler.options.data.page = 1;
  206. handler._init();
  207. }
  208. });
  209. /*var limitArr = [ 10, 50, 100 ];
  210. for ( var i = 0; i < limitArr.length; i++) {
  211. foot.find("select[limit]").append("<option value='" + limitArr[i] + "' " + (limitArr[i] == limit ? "selected" : "") + ">" + limitArr[i] + "条</option>");
  212. }*/
  213. }
  214. },
  215. initialized : false,
  216. // 设置表头,以及表头排序功能,排序时不重新获取数据,只根据数据缓存重新排序
  217. _create : function() {
  218. var div = $(this.element);
  219. div.addClass("yab");
  220. var table = div.find("table");
  221. div.css("width", "100%");
  222. div.addClass("ui-widget");
  223. table.css("width", "100%");
  224. table.attr("data", "true");
  225. table.addClass("table table-bordered");
  226. var header = this.options.header;
  227. if (this.options.select != null) {
  228. header = $.merge([ {
  229. code : this.options.select,
  230. name : "<input type='checkbox' batch />"
  231. } ], header);
  232. }
  233. if (this.options.sequence != null) {
  234. header = $.merge([ {
  235. code : this.options.sequence,
  236. name : "序号"
  237. } ], header);
  238. }
  239. var s = '<thead><tr class="ui-widget-header table-header">';
  240. for ( var i = 0; i < header.length; i++)
  241. s += "<th code='" + header[i].code + "' style='text-align:center;'><span>" + header[i].name + "</span></th>";
  242. s += '</tr></thead><tbody></tbody>';
  243. table.append(s);
  244. if (this.options.select != null){
  245. table.find("thead").find("th[code=" + this.options.select + "]").find("input[batch]").click(function(handler) {
  246. return function() {
  247. var checked = this.checked;
  248. table.find("tbody").find("input[name=" + handler.options.select + "]:visible").each(function() {
  249. if($(this).attr("disabled")!="disabled"){
  250. this.checked = checked;
  251. }
  252. });
  253. };
  254. }(this));
  255. }
  256. if (this.options.data.page != null)
  257. table.append('<tfoot><tr class="table-footer"><td colspan="' + header.length + '"></td></tr></tfoot>');
  258. var th = table.find("thead").find("tr").find("th");
  259. var i = 0;
  260. th.each(function() {
  261. var val = header[i++];
  262. if (val.width != undefined) {
  263. $(this).width(val.width);
  264. }
  265. });
  266. if (this.options.title != null)
  267. $(this.element).prepend("<h3 align=\"center\">" + this.options.title + "</h3>");
  268. if(this.options.sort){
  269. th.hover(function() {
  270. $(this).addClass("t3");
  271. $(this).css("cursor", "pointer");
  272. }, function() {
  273. $(this).removeClass("t3");
  274. });
  275. th.click(function(handler) {
  276. return function() {
  277. if (handler.options.select != null && handler.options.select == $(this).attr("code")) {
  278. return;
  279. }
  280. if (handler.options.sort != $(this).attr("code")) {
  281. handler.options.order = 0;
  282. }
  283. $(this).parent().find("th").find("span").removeClass(" ui-icon ui-icon-carat-1-n ui-icon-carat-1-s ");
  284. if (handler.options.order == 0) {
  285. $(this).find("span").addClass(" ui-icon ui-icon-carat-1-n ");
  286. handler.options.order = 1;
  287. } else if (handler.options.order == 1) {
  288. $(this).find("span").addClass(" ui-icon ui-icon-carat-1-s ");
  289. handler.options.order = -1;
  290. } else if (handler.options.order == -1) {
  291. handler.options.order = 0;
  292. }
  293. handler.options.sort = $(this).attr("code");
  294. handler.clear();
  295. handler.setupData();
  296. if (handler.options.data.page != null)
  297. handler.setupPage();
  298. };
  299. }(this));
  300. }
  301. },
  302. // 刷新数据
  303. _init : function() {
  304. if (this.options.url != null) {
  305. var data = {};
  306. if (this.options.data != null && !$.isArray(this.options.data)) {
  307. data = this.options.data;
  308. } else if (this.options.data.page != null) {
  309. if (this.options.data.page != null) {
  310. data[this.options.pageField] = this.options.data.page;
  311. }
  312. if (this.options.data.limit != null) {
  313. data[this.options.limitField] = this.options.data.limit;
  314. }
  315. }
  316. //this.clear();
  317. $.request({
  318. action : this.options.url,
  319. data : data,
  320. success : function(handler) {
  321. return function(data) {
  322. handler.clear();//处理多次初始化的情况,每次先将数据清除
  323. handler.data = data[handler.options["dataField"]];
  324. handler.result = data;
  325. if (handler.options.data.page != null) {
  326. var page = data[handler.options["pagingField"]];
  327. if (page != undefined) {
  328. handler.options.maxRows = page.maxRows;
  329. handler.options.data.limit = page.limit;
  330. handler.options.data.page = page.page;
  331. }
  332. }
  333. handler.setupData();
  334. if (handler.options.data.page != null) {
  335. handler.setupPage();
  336. }
  337. }
  338. }(this),
  339. error : function(handler) {
  340. return function(data) {
  341. if (handler.options.error != null)
  342. handler.options.error(data);
  343. }
  344. }(this)
  345. });
  346. } else if (this.options.input != null) {
  347. if ($.isArray(this.options.input)) {
  348. this.options.maxRows = this.options.input.length;
  349. if (this.options.data.page != null) {
  350. var start = ((this.options.data.page - 1) * this.options.data.limit);
  351. if (start < 0)
  352. start = 0;
  353. this.data = this.options.input.slice(start, start + this.options.data.limit);
  354. } else {
  355. this.options.data.limit = this.options.maxRows;
  356. this.data = this.options.input;
  357. }
  358. } else {
  359. var obj = this.options.input();
  360. this.data = obj.data;
  361. if (obj.limit != null)
  362. this.options.data.limit = obj.limit;
  363. if (obj.maxRows != null)
  364. this.options.maxRows = obj.maxRows;
  365. if (obj.page != null)
  366. this.options.data.page = obj.page;
  367. }
  368. this.clear();
  369. this.setupData();
  370. if (this.options.data.page != null) {
  371. this.setupPage();
  372. }
  373. }
  374. },
  375. // 清理表体数据
  376. clear : function() {
  377. $(this.element).find("table").find("tbody").empty();
  378. if (this.options.select != null) {
  379. var choiceAll = $(this.element).find("table").find("thead").find("th[code=" + this.options.select + "]").find("input[batch]");
  380. choiceAll.prop("checked",false);
  381. }
  382. },
  383. // 排序比较函数
  384. sortData : function(sort, order) {
  385. return function(x, y) {
  386. var xs = x[sort] == undefined ? "" : x[sort];
  387. var ys = y[sort] == undefined ? "" : y[sort];
  388. return xs > ys ? order : xs < ys ? order * -1 : 0;
  389. };
  390. },
  391. // 设置表体数据
  392. setupData : function() {
  393. var header = this.options.header;
  394. if (this.options.select != null) {
  395. header = $.merge([ {
  396. code : this.options.select
  397. } ], header);
  398. }
  399. if (this.options.sequence != null) {
  400. header = $.merge([ {
  401. code : this.options.sequence
  402. } ], header);
  403. }
  404. var data = this.data.slice(0);
  405. if (this.options.sort != null && this.options.order != 0) {
  406. data.sort(this.sortData(this.options.sort, this.options.order));
  407. }
  408. var s = '';
  409. for ( var i = 0; i < data.length; i++) {
  410. s += "<tr class=\"" + (i % 2 == 0 ? "t1" : "t2") + "\">";
  411. for ( var j = 0; j < header.length; j++) {
  412. var val = null;
  413. if (this.options.select == header[j].code) {
  414. val = "<input type='checkbox' name='" + header[j].code + "' />";
  415. } else if(header[j].type == "amount"){
  416. val = $.toCashWithCommaAndDot(data[i][header[j].code]+"");
  417. }else{
  418. val = data[i][header[j].code];
  419. }
  420. s += "<td " + ((header[j].title == null || (data[i][header[j].title] == undefined)) ? "" : "title='" + data[i][header[j].title] + "'") + " code='" + header[j].code + "' align='center'>";
  421. s += val == undefined ? "" : val;
  422. s += "</td>";
  423. }
  424. s += "</tr>";
  425. }
  426. $(this.element).find("table").append(s);
  427. var tr = $(this.element).find("table").find("tbody").find("tr");
  428. var i = 0;
  429. tr.each(function() {
  430. $(this).val(data[i++]);
  431. });
  432. tr.hover(function() {
  433. $(this).addClass("t3");
  434. }, function() {
  435. $(this).removeClass("t3");
  436. });
  437. if (this.options.complete != null) {
  438. this.options.complete(data, this.result);
  439. }
  440. if (this.options.sequence != null) {
  441. var i = 1, page = this.options.data.page, limit = this.options.data.limit;
  442. $(this.element).find("table").find("td[code='" + this.options.sequence + "']").each(function() {
  443. $(this).html(i++ - 0 + (page - 1) * limit);
  444. });
  445. }
  446. //全选时选中全选框
  447. $(this.element).find("table").find("input[type=checkbox][name=" + this.options.select + "]").click(function(handler){
  448. return function(){
  449. var checkboxNum = $(handler.element).find("table").find("input[type=checkbox][name=" + handler.options.select + "]:visible").length;
  450. var checkedNum = $(handler.element).find("table").find("input[type=checkbox][name=" + handler.options.select + "]:checked").length;
  451. if(checkboxNum == checkedNum){
  452. $(handler.element).find("table").find("input[batch]").prop("checked",true);
  453. }else{
  454. $(handler.element).find("table").find("input[batch]").prop("checked",false);
  455. }
  456. }
  457. }(this));
  458. //对全选框初始化
  459. var checkboxNum = $(this.element).find("table").find("input[type=checkbox][name=" + this.options.select + "]:visible").length;
  460. var checkedNum = $(this.element).find("table").find("input[type=checkbox][name=" + this.options.select + "]:checked").length;
  461. if(checkedNum>0 && checkboxNum == checkedNum){
  462. $(this.element).find("table").find("input[batch]").prop("checked",true);
  463. }else{
  464. $(this.element).find("table").find("input[batch]").prop("checked",false);
  465. }
  466. },
  467. // 设置分页数据
  468. setupPage : function() {
  469. var tfoot=$(this.element).find("table").find("tfoot");
  470. var foot = $(this.element).find("table").find("tfoot").find("tr").find("td");
  471. if(this.options.maxRows>this.options.data.limit){
  472. tfoot.show();
  473. foot.html("");
  474. foot.children().remove();
  475. var cur = this.options.data.page;
  476. cur = cur < 0 ? 0 : cur > this.options.maxRows ? this.options.maxRows : cur;
  477. cur = cur - 0;
  478. var first = 1;
  479. var last = Math.floor(((this.options.maxRows - 1) / this.options.data.limit) + 1);
  480. var prev = cur > first ? cur - 1 : first;
  481. var next = cur < last ? cur + 1 : last;
  482. var start = ((this.options.data.page - 1) * this.options.data.limit);
  483. if (start < 0)
  484. start = 0;
  485. start = start + 1;
  486. this.options.paging(this, foot, cur, start, this.options.data.limit, this.options.maxRows, first, last, prev, next);
  487. }else{
  488. tfoot.hide();
  489. if(this.result.MINQueryResult.length==0){
  490. tfoot.show();
  491. foot.html("没有查询记录!");
  492. }
  493. }
  494. },
  495. destroy : function() {
  496. // 有需要再写
  497. }
  498. });