table-edit.html 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. <!DOCTYPE html>
  2. <html lang="en" xmlns:th="http://www.thymeleaf.org">
  3. <head>
  4. <meta charset="utf-8">
  5. <title>layui可编辑table示例</title>
  6. <meta name="renderer" content="webkit">
  7. <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  8. <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  9. <link rel="stylesheet" th:href="@{/lib/layui/css/layui.css}" media="all">
  10. <link rel="stylesheet" th:href="@{/css/public.css}" media="all">
  11. <style type="text/css">
  12. /*您可以将下列样式写入自己的样式表中*/
  13. .childBody {
  14. padding: 15px;
  15. }
  16. /*layui 元素样式改写*/
  17. .layui-btn-sm {
  18. line-height: normal;
  19. font-size: 12.5px;
  20. }
  21. .layui-table-view .layui-table-body {
  22. min-height: 256px;
  23. }
  24. .layui-table-cell .layui-input.layui-unselect {
  25. height: 30px;
  26. line-height: 30px;
  27. }
  28. /*设置 layui 表格中单元格内容溢出可见样式*/
  29. .table-overlay .layui-table-view,
  30. .table-overlay .layui-table-box,
  31. .table-overlay .layui-table-body {
  32. overflow: visible;
  33. }
  34. .table-overlay .layui-table-cell {
  35. height: auto;
  36. overflow: visible;
  37. }
  38. /** 数据表格中的input尺寸调整 */
  39. .layui-table-view .layui-table-cell .layui-input {
  40. height: 32px;
  41. line-height: 32px;
  42. }
  43. /*文本对齐方式*/
  44. .text-center {
  45. text-align: center;
  46. }
  47. </style>
  48. </head>
  49. <body class="childBody">
  50. <section class="layui-col-md10" style="margin: 0 auto; float: none;">
  51. <div class="layui-card">
  52. <div class="layui-card-header">layui可编辑table示例</div>
  53. <div class="layui-card-body layui-text">
  54. <div id="toolbar">
  55. <div>
  56. <button type="button" class="layui-btn layui-btn-sm" data-type="addRow" title="添加一行">
  57. <i class="layui-icon layui-icon-add-1"></i> 添加一行
  58. </button>
  59. </div>
  60. </div>
  61. <div id="tableRes" class="table-overlay">
  62. <table id="dataTable" lay-filter="dataTable" class="layui-hide"></table>
  63. </div>
  64. <div id="action" class="text-center">
  65. <button type="button" name="btnSave" class="layui-btn" data-type="save">
  66. <i class="layui-icon layui-icon-ok-circle"></i>保存
  67. </button>
  68. <button type="reset" name="btnReset" class="layui-btn layui-btn-primary">
  69. 取消
  70. </button>
  71. </div>
  72. </div>
  73. </div>
  74. <!--保存结果输出-->
  75. <div class="layui-card">
  76. <div class="layui-card-header">保存结果输出</div>
  77. <div class="layui-card-body layui-text">
  78. <blockquote class="layui-elem-quote layui-quote-nm">
  79. <pre id="jsonResult"><span class="layui-word-aux">请点击“保存”后查看输出信息……</span></pre>
  80. </blockquote>
  81. </div>
  82. </div>
  83. </section>
  84. <script th:src="@{/lib/layui/layui.js}" charset="utf-8"></script>
  85. <script type="text/javascript">
  86. //准备视图对象
  87. window.viewObj = {
  88. tbData: [{
  89. tempId: new Date().valueOf(),
  90. type: 2,
  91. name: '测试项名称',
  92. state: 1,
  93. paydate: '20220413',
  94. paydesc: '测试说明'
  95. }],
  96. typeData: [
  97. {id: 1, name: '分类一'},
  98. {id: 2, name: '分类二'},
  99. {id: 3, name: '分类三'},
  100. {id: 4, name: '分类四'}
  101. ],
  102. renderSelectOptions: function (data, settings) {
  103. settings = settings || {};
  104. var valueField = settings.valueField || 'value',
  105. textField = settings.textField || 'text',
  106. selectedValue = settings.selectedValue || "";
  107. var html = [];
  108. for (var i = 0, item; i < data.length; i++) {
  109. item = data[i];
  110. html.push('<option value="');
  111. html.push(item[valueField]);
  112. html.push('"');
  113. if (selectedValue && item[valueField] == selectedValue) {
  114. html.push(' selected="selected"');
  115. }
  116. html.push('>');
  117. html.push(item[textField]);
  118. html.push('</option>');
  119. }
  120. return html.join('');
  121. }
  122. };
  123. //layui 模块化引用
  124. layui.use(['jquery', 'table', 'layer', 'laydate'], function () {
  125. var $ = layui.$, table = layui.table, form = layui.form, laydate = layui.laydate, layer = layui.layer;
  126. //数据表格实例化
  127. var tbWidth = $("#tableRes").width();
  128. var layTableId = "layTable";
  129. var tableIns = table.render({
  130. elem: '#dataTable',
  131. id: layTableId,
  132. data: viewObj.tbData,
  133. width: tbWidth,
  134. page: false,
  135. limit: Number.MAX_VALUE,
  136. loading: true,
  137. even: false, //不开启隔行背景
  138. cols: [
  139. [
  140. {title: '序号', type: 'numbers'},
  141. {
  142. field: 'type', title: '分类(type)', templet: function (d) {
  143. var options = viewObj.renderSelectOptions(viewObj.typeData, {
  144. valueField: "id",
  145. textField: "name",
  146. selectedValue: d.type
  147. });
  148. return '<a lay-event="type"></a><select name="type" lay-filter="type"><option value="">请选择分类</option>' + options + '</select>';
  149. }
  150. },
  151. {
  152. field: 'name',
  153. title: '名称(name)',
  154. edit: 'text',
  155. style: 'outline: 1px solid #e6e6e6;outline-offset: -6px;overflow: hidden;text-overflow: ellipsis;'
  156. },
  157. {
  158. field: 'paydate', title: '发生日期', width: 130, templet: function (d) {
  159. return '<input type="text" name="paydate" id="paydate-' + d.tempId + '" lay-verify="required" placeholder="YYYYMMDD" autocomplete="off" class="layui-input" value="' + d.paydate + '" readonly lay-reqtext="发生日期不得为空>_<">';
  160. }
  161. },
  162. {
  163. field: 'paydesc', title: '描述', width: 180, templet: function (d) {
  164. return '<input type="text" name="paydesc" id="paydesc-' + d.tempId + '" lay-verify="required" placeholder="描述" autocomplete="off" class="layui-input" value="' + d.paydesc + '" lay-reqtext="描述不得为空>_<">';
  165. }
  166. },
  167. {
  168. field: 'state', title: '是否启用(state)', event: 'state', templet: function (d) {
  169. var html = ['<input type="checkbox" name="state" lay-skin="switch" lay-text="是|否"'];
  170. html.push(d.state > 0 ? ' checked' : '');
  171. html.push('/>');
  172. return html.join('');
  173. }
  174. },
  175. {
  176. field: 'tempId', title: '操作', templet: function (d) {
  177. return '<a class="layui-btn layui-btn-xs layui-btn-danger" lay-event="del" lay-id="' + d.tempId + '"><i class="layui-icon layui-icon-delete"></i>移除</a>';
  178. }
  179. }
  180. ]
  181. ],
  182. done: function (res, curr, count) {
  183. viewObj.tbData = res.data;
  184. res.data.forEach(item => {
  185. // 初始化laydate
  186. laydate.render({
  187. elem: '#paydate-' + item.tempId,
  188. format: 'yyyyMMdd',
  189. //type: 'month', //year time datetime
  190. //value: new Date(),
  191. //min: 0,
  192. //max: lastDay,
  193. trigger: 'click', //日期框只能点击选择,不能手动输入
  194. done: function (value, date, endDate) {
  195. if (!!value) {
  196. item.paydate = value;
  197. } else {
  198. item.paydate = '20220413';
  199. }
  200. console.log(value);
  201. }
  202. });
  203. // 监听input name="paydesc" 的输入框
  204. var paydesc_id = 'paydesc-' + item.tempId;
  205. $("#" + paydesc_id + "").on("input", function(e){
  206. item.paydesc = e.delegateTarget.value;
  207. });
  208. })
  209. }
  210. });
  211. // 定义事件集合
  212. var active = {
  213. // 添加一行
  214. addRow: function () {
  215. // var oldData = table.cache[layTableId];
  216. var oldData = table.getData(layTableId);
  217. console.log(oldData);
  218. var newRow = {
  219. tempId: new Date().valueOf(),
  220. type: null,
  221. name: '请填写名称',
  222. paydate: '',
  223. paydesc: '',
  224. state: 0
  225. };
  226. oldData.push(newRow);
  227. tableIns.reload({
  228. data: oldData
  229. });
  230. },
  231. // 修改一行
  232. updateRow: function (obj) {
  233. // var oldData = table.cache[layTableId];
  234. var oldData = table.getData(layTableId);
  235. console.log(oldData);
  236. for (var i = 0, row; i < oldData.length; i++) {
  237. row = oldData[i];
  238. if (row.tempId == obj.tempId) {
  239. $.extend(oldData[i], obj);
  240. return;
  241. }
  242. }
  243. tableIns.reload({
  244. data: oldData
  245. });
  246. },
  247. // 删除一行
  248. removeEmptyTableCache: function () {
  249. // var oldData = table.cache[layTableId];
  250. var oldData = table.getData(layTableId);
  251. for (var i = 0, row; i < oldData.length; i++) {
  252. row = oldData[i];
  253. if (!row || !row.tempId) {
  254. oldData.splice(i, 1); //删除一项
  255. }
  256. continue;
  257. }
  258. tableIns.reload({
  259. data: oldData
  260. });
  261. },
  262. save: function () {
  263. // var oldData = table.cache[layTableId];
  264. var oldData = table.getData(layTableId);
  265. console.log(oldData);
  266. for (var i = 0, row; i < oldData.length; i++) {
  267. row = oldData[i];
  268. if (!row.type) {
  269. layer.msg("检查每一行,请选择分类!", {icon: 5}); //提示
  270. return;
  271. }
  272. }
  273. document.getElementById("jsonResult").innerHTML = JSON.stringify(table.cache[layTableId], null, 2); //使用JSON.stringify() 格式化输出JSON字符串
  274. }
  275. }
  276. // 激活事件
  277. var activeByType = function (type, arg) {
  278. // arguments.length表示实际上向函数传入了多少个参数
  279. if (arguments.length === 2) {
  280. active[type] ? active[type].call(this, arg) : '';
  281. } else {
  282. active[type] ? active[type].call(this) : '';
  283. }
  284. }
  285. // 注册按钮事件
  286. $('.layui-btn[data-type]').on('click', function () {
  287. var type = $(this).data('type'); // var type的值其实就等于addRow ,就是data-type里配置的值
  288. activeByType(type);
  289. });
  290. // 监听select下拉选中事件
  291. form.on('select(type)', function (data) {
  292. var elem = data.elem; //得到select原始DOM对象
  293. $(elem).prev("a[lay-event='type']").trigger("click");
  294. });
  295. // 监听table工具条
  296. table.on('tool(dataTable)', function (obj) {
  297. var data = obj.data,
  298. event = obj.event,
  299. tr = obj.tr; // 获得当前行 tr 的DOM对象;
  300. console.log(data);
  301. switch (event) {
  302. case "type":
  303. var select = tr.find("select[name='type']");
  304. if (select) {
  305. var selectedVal = select.val();
  306. if (!selectedVal) {
  307. layer.tips("请选择一个分类", select.next('.layui-form-select'), {tips: [3, '#FF5722']}); //吸附提示
  308. }
  309. console.log(selectedVal);
  310. $.extend(obj.data, {'type': selectedVal});
  311. activeByType('updateRow', obj.data); //更新行记录对象
  312. }
  313. break;
  314. case "state":
  315. var stateVal = tr.find("input[name='state']").prop('checked') ? 1 : 0;
  316. $.extend(obj.data, {'state': stateVal})
  317. activeByType('updateRow', obj.data); //更新行记录对象
  318. break;
  319. case "del":
  320. layer.confirm('真的删除行么?', function (index) {
  321. obj.del(); //删除对应行(tr)的DOM结构,并更新缓存
  322. layer.close(index);
  323. activeByType('removeEmptyTableCache');
  324. });
  325. break;
  326. }
  327. });
  328. });
  329. </script>
  330. </body>
  331. </html>