yvanui.grid.edit.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529
  1. /**
  2. * yvan.grid.edit.js
  3. * @author luoyifan
  4. * 2018-12-07 18:37:00
  5. */
  6. 'use strict';
  7. (function ($) {
  8. var WIDTH_OFFSET = -1;
  9. if (!$.jgrid) {
  10. console.warn('no jqGrid!!');
  11. return;
  12. }
  13. function runtimeCreateCtl(elem, operation, value) {
  14. var $editor = $(elem).find('input[xtype]');
  15. var editor = $editor.data('jqeditor').editor;
  16. if ($.inArray(editor.xtype, ["textbox", "searchbox", "datebox", "numberbox"]) >= 0) {
  17. //================= textbox 赋值
  18. if (operation === 'get') {
  19. return $editor.textbox('getText');
  20. } else if (operation === 'set') {
  21. if (editor.xtype === 'numberbox') {
  22. if (!value) {
  23. value = 0;
  24. }
  25. if (editor.precision) {
  26. value = parseFloat(value).toFixed(editor.precision);
  27. }
  28. }
  29. $editor.textbox('initValue', value);
  30. }
  31. } else if ($.inArray(editor.xtype, ["combobox"]) >= 0) {
  32. //================= combobox
  33. if (operation === 'get') {
  34. return $editor.combobox('getValue');
  35. } else if (operation === 'set') {
  36. $editor.combobox('initValue', value);
  37. $editor.combobox('setValue', value);
  38. }
  39. } else if (editor.xtype === 'checkbox') {
  40. //================= checkbox
  41. if (operation === 'get') {
  42. if ($editor.checkbox('isChecked')) {
  43. return editor.on;
  44. }
  45. return editor.off;
  46. } else if (operation === 'set') {
  47. $editor.checkbox('initValue', value === editor.on);
  48. }
  49. } else {
  50. console.error('不支持的编辑方式:', options);
  51. }
  52. return '';
  53. }
  54. function runtimeCreateInput(value, options) {
  55. var $grid = $(this);
  56. var colOption = options.cm;
  57. var editor = colOption.editor;
  58. var f = colOption.editor.onChange;
  59. colOption.editor.onChange = function (a,b) {
  60. $grid.setGridParam({ 'beEdited': true });
  61. if ($.type(f) === 'function')
  62. {
  63. f(a,b);
  64. }
  65. };
  66. var id = $.yvan.createId('e');
  67. var $editor = $('<input id="' + id + '" />');
  68. $editor.attr('name', colOption.name);
  69. $editor.attr('itemId', colOption.name);
  70. $editor.attr('xtype', editor.xtype);
  71. $editor.data({ jqeditor: colOption });
  72. var $div = $('<div></div>');
  73. $div.append($editor);
  74. //$div.css({ width: colOption.width - WIDTH_OFFSET });
  75. //$div.css({ width: colOption.width - WIDTH_OFFSET });
  76. $('body').append($div);
  77. if ($.inArray(editor.xtype, ["textbox", "searchbox", "datebox", "numberbox"]) >= 0) {
  78. $editor[editor.xtype](
  79. $.extend({
  80. width: colOption.width - WIDTH_OFFSET,
  81. tipPosition: 'bottom'
  82. }, editor)
  83. );
  84. if (editor.xtype === 'searchbox') {
  85. $editor.searchbox('onSysRender');
  86. }
  87. } else if ($.inArray(editor.xtype, ["combobox"]) >= 0) {
  88. $editor[editor.xtype](
  89. $.extend({
  90. width: colOption.width - WIDTH_OFFSET,
  91. tipPosition: 'right'
  92. }, editor)
  93. );
  94. } else if (editor.xtype === 'checkbox') {
  95. $editor.checkbox($.extend({
  96. tipPosition: 'bottom'
  97. }, editor));
  98. } else {
  99. console.error('不支持的编辑方式:', colOption);
  100. }
  101. options.custom_value($div, 'set', value);
  102. return $div;
  103. }
  104. $.jgrid.chain.onReload.push(function (rowid) {
  105. //重新载入数据时,要立刻结束当前编辑状态
  106. var $grid = $(this);
  107. if ($grid.editRowId()) {
  108. $grid.cancelEditRow();
  109. }
  110. });
  111. $.jgrid.chain.beforeSelectRow.push(function (rowid, e) {
  112. //编辑状态下,不允许切换行
  113. var $grid = $(this);
  114. var cellIndex = e.target.cellIndex || 'null';
  115. $grid.lastClickCol(cellIndex);
  116. if ($grid.getGridParam('multiselect')) {
  117. //多选状态下
  118. if (cellIndex === 'null') {
  119. //通过勾选而产生的事件,不校验、也不切换编辑行
  120. if ($grid.editRowId()) {
  121. //在多选状态下,当前正在编辑的行,无法取消选择的bug
  122. $grid.getGridParam().multiNeedTo = ($.inArray(rowid, $grid.getGridParam('selarrrow')) < 0);
  123. }
  124. return true;
  125. }
  126. }
  127. if (rowid === $grid.editRowId()) {
  128. //如果要跳转的行,就是当前编辑行,就静默拦截
  129. return false;
  130. }
  131. if ($grid.jqGrid('getGridParam', 'editable') &&
  132. $grid.jqGrid('getGridParam', 'editOnSelected')) {
  133. //编辑状态下,需要校验当前行是否通过校验
  134. var vr = $grid.validateRow();
  135. //没有通过校验
  136. if (vr === false) return false;
  137. return true;
  138. }
  139. if ($grid.jqGrid('getGridParam', 'editable') && !$grid.jqGrid('getGridParam', 'editOnSelected')) {
  140. //不是 editOnSelected,需要禁用行选择
  141. if ($grid.editRowId()) {
  142. if ($grid.editRowId() !== rowid) {
  143. $.yvan.msg('请先结束编辑,再进行选择');
  144. }
  145. return false;
  146. }
  147. }
  148. return true;
  149. });
  150. $.jgrid.chain.onSelectRow.push(function (rowid, e) {
  151. var $grid = $(this);
  152. var colIndex = $grid.lastClickCol();
  153. if ($grid.getGridParam('multiselect')) {
  154. //多选状态
  155. if (colIndex === 'null') {
  156. //通过勾选而产生的事件,不校验、也不切换编辑行
  157. if ($grid.editRowId()) {
  158. //在多选状态下,当前正在编辑的行,无法取消选择的bug
  159. var needTo = $grid.getGridParam('multiNeedTo');
  160. if (!needTo) {
  161. $grid.resetSelection(rowid);
  162. }
  163. }
  164. return;
  165. }
  166. }
  167. //console.log('onSelectRow', rowid, $grid.lastClickCol() ? $grid.lastClickCol().name : '');
  168. var col = $grid.getCol(colIndex);
  169. $grid.lastClickCol(null);
  170. if ($grid.jqGrid('getGridParam', 'editable') && $grid.jqGrid('getGridParam', 'editOnSelected')) {
  171. //如果需要选择后立即进入编辑状态
  172. $grid.editRow2(rowid, col);
  173. }
  174. });
  175. $.jgrid.chain.prepearOption.push(function (opts,grid) {
  176. if (opts.colModel) {
  177. for (var i = 0; i < opts.colModel.length; i++) {
  178. var colOption = opts.colModel[i];
  179. if (!colOption.editable) {
  180. //如果不允许编辑,就不用走下面的编辑器运行时设置了
  181. continue;
  182. }
  183. $.extend(true, colOption, {
  184. editable: true,
  185. edittype: 'custom',
  186. editoptions: {
  187. // 把
  188. custom_element: runtimeCreateInput,//function(value, options){return runtimeCreateInput(value, options, grid)} ,
  189. custom_value: runtimeCreateCtl//function(elem, operation, value){return runtimeCreateCtl(elem, operation, value, grid)}
  190. }
  191. });
  192. }
  193. }
  194. });
  195. $.jgrid.chain.ondblClickRow.push(function (rowid, iRow, iCol, e) {
  196. var $grid = $(this);
  197. var editable = $grid.jqGrid('getGridParam', 'editable');
  198. if (editable) {
  199. if ($grid.jqGrid('getGridParam', 'editOnDblClick')) {
  200. $grid.setSelection(rowid, true);
  201. $grid.editRow2(rowid, $grid.getCol(iCol));
  202. }
  203. }
  204. });
  205. $.jgrid.chain.onKeydown.push(function (e) {
  206. var $grid = $(this);
  207. if ($.type($grid.getGridParam().onKeyDown) === 'function') {
  208. $grid.getGridParam().onKeyDown(e);
  209. }
  210. if (e.key === 'Escape') {
  211. $grid.cancelEditRow();
  212. return true;
  213. } else if (e.key === 'Enter') {
  214. $grid.editRow2();
  215. return true;
  216. }
  217. if ($grid.editRowId()) {
  218. //在编辑状态
  219. if (e.key === 'ArrowDown') {
  220. console.log('down');
  221. return true;
  222. } else if (e.key === 'ArrowUp') {
  223. console.log('up');
  224. return true;
  225. }
  226. }
  227. });
  228. //================= 扩展属性 =================
  229. function beginEditRow(data) {
  230. var $grid = $(this);
  231. return function (rowid) {
  232. $grid.editRowId(rowid);
  233. var onBeginEditRow = $grid.getGridParam('onBeginEditRow');
  234. if (onBeginEditRow) {
  235. onBeginEditRow.call($grid[0], rowid, data);
  236. }
  237. //$grid.findBox().find('input.cbox').attr("disabled", "disabled");
  238. $grid.editRowData($.extend({}, data));
  239. $grid.editRowDataOrg($.extend({}, data));
  240. };
  241. }
  242. function restoreEditRow() {
  243. var $grid = $(this);
  244. return function () {
  245. var onRestoryEditRow = $grid.getGridParam('onRestoryEditRow');
  246. var editRowId = $grid.editRowId();
  247. var editRowDataOrg = $grid.editRowDataOrg();
  248. if (onRestoryEditRow) {
  249. onRestoryEditRow.call(this, editRowId, editRowDataOrg);
  250. }
  251. if (!editRowDataOrg) {
  252. $grid.deleteRow(editRowId);
  253. } else {
  254. $grid.jqGrid('setRowData', editRowId, editRowDataOrg);
  255. }
  256. $grid.editRowId(null);
  257. //$grid.findBox().find('input.cbox').removeAttr("disabled");
  258. };
  259. }
  260. function getEditRow() {
  261. var $grid = $(this);
  262. var editRowId = $grid.editRowId();
  263. if (!editRowId) return;
  264. //取到所有的编辑器,并从编辑器中取值
  265. var cols = $grid.getCol();
  266. var editRowData = $grid.editRowData();
  267. var r = $.extend({}, editRowData);
  268. for (var i = 0; i < cols.length; i++) {
  269. if (cols[i].hasOwnProperty('editoptions') && cols[i].editoptions.hasOwnProperty('custom_value')) {
  270. var $editor = $grid.item(cols[i].name).parent();
  271. r[cols[i].name] = cols[i].editoptions.custom_value($editor, 'get');
  272. }
  273. }
  274. return r;
  275. }
  276. function setEditRow(data) {
  277. var $grid = $(this);
  278. var editRowId = $grid.editRowId();
  279. if (!editRowId) return;
  280. var onReadysetEditRow = $grid.getGridParam('onReadysetEditRow');
  281. if (onReadysetEditRow) {
  282. onReadysetEditRow.call(this, editRowId, data);
  283. }
  284. var editRowData = $grid.editRowData();
  285. for (var name in data) {
  286. if (!data.hasOwnProperty(name) || !editRowData.hasOwnProperty(name)) {
  287. console.error('data 或 grid 不存在的属性', name);
  288. continue;
  289. }
  290. //var col = $grid.getCol(name);
  291. var col = $grid.jqGrid('getColProp', name);
  292. if (!col) {
  293. console.error('grid 不存在的属性', name);
  294. continue;
  295. }
  296. editRowData[name] = data[name];
  297. if (col.hasOwnProperty('editoptions') &&
  298. col.hasOwnProperty('editor') &&
  299. col.editoptions.hasOwnProperty('custom_value')) {
  300. //找到编辑器赋值
  301. var $editor = $grid.item(col.name).parent();
  302. col.editoptions.custom_value($editor, 'set', editRowData[col.name]);
  303. } else {
  304. //单元格赋值
  305. if (!editRowData[col.name]) {
  306. editRowData[col.name] = '\x00';
  307. }
  308. $grid.setCell(editRowId, col.name, editRowData[col.name]);
  309. }
  310. }
  311. }
  312. function validateRow() {
  313. var $grid = $(this);
  314. var editRowId = $grid.editRowId();
  315. if (!editRowId) return;
  316. var $form = $grid.closest('form');
  317. var vbox = $form.find(".validatebox-text");
  318. vbox.validatebox("validate");
  319. var r = $form.find(".validatebox-invalid");
  320. var onValidateEditRow = $grid.getGridParam('onValidateEditRow');
  321. if (onValidateEditRow) {
  322. onValidateEditRow.call(this, editRowId, r);
  323. }
  324. if (r.length > 0) {
  325. $grid.showEditError(r);
  326. return false;
  327. }
  328. return true;
  329. }
  330. function saveEditRow() {
  331. var $grid = $(this);
  332. var editRowId = $grid.editRowId();
  333. if (!editRowId) return false;
  334. $grid.findBox().find('input.cbox').removeAttr("disabled");
  335. var onSaveEditRow = $grid.getGridParam('onSaveEditRow');
  336. if (onSaveEditRow) {
  337. onSaveEditRow.call(this, editRowId);
  338. }
  339. if (!validateRow.call(this)) {
  340. return false;
  341. }
  342. $grid.saveRow(editRowId, true, 'clientArray');
  343. $grid.editRowId(null);
  344. return true;
  345. }
  346. function editRow(rowid, focusColumnOption) {
  347. var $grid = $(this);
  348. var editRowId = $grid.editRowId();
  349. rowid = rowid || $grid.selrow();
  350. if (rowid === editRowId) {
  351. return true;
  352. }
  353. if (editRowId) {
  354. //尽量保存当前编辑行
  355. if (!saveEditRow.call(this)) {
  356. //如果保存不成功
  357. return false;
  358. }
  359. }
  360. $grid.jqGrid('editRow', rowid,
  361. {
  362. keys: false,
  363. oneditfunc: beginEditRow.call(this, $grid.rowData(rowid)),
  364. url: 'clientArray',
  365. afterrestorefunc: restoreEditRow.call(this)
  366. }
  367. );
  368. //focus
  369. if (focusColumnOption && focusColumnOption.editable) {
  370. //列允许编辑
  371. setTimeout(function () {
  372. var text = $grid.closest('form').find('[itemId=' + focusColumnOption.name + ']');
  373. if (text && text.data('textbox')) {
  374. setTimeout(function () {
  375. text.textbox('textbox')[0].focus();
  376. });
  377. }
  378. }, 20);
  379. }
  380. }
  381. $.jgrid.extend({
  382. getEditRow: getEditRow,
  383. setEditRow: setEditRow,
  384. validateRow: validateRow,
  385. showEditError: function (r) {
  386. $.yvan.msg('有 <span style="color:greenyellow;font-weight: bolder;font-size: 33px;">' + r.length + '</span> 项校验未通过!请核对后再进行操作');
  387. r[0].focus();
  388. },
  389. addRowForEdit: function (rowData) {
  390. var $grid = $(this);
  391. var editRowId = $grid.editRowId();
  392. if (editRowId) {
  393. if (!saveEditRow.call(this)) {
  394. return false;
  395. }
  396. }
  397. var rowId = $.yvan.createId('nr');
  398. $grid.addRowData(rowId, rowData, "last");
  399. $grid.jqGrid('setSelection', rowId, false);
  400. editRow.call(this, rowId);
  401. $grid.editRowDataOrg(null);
  402. },
  403. editRow2: editRow,
  404. cancelEditRow: function () {
  405. var $grid = $(this);
  406. var editRowId = $grid.editRowId();
  407. if (!editRowId) return;
  408. $grid.jqGrid('restoreRow', editRowId, restoreEditRow.call(this));
  409. setTimeout(function () {
  410. $('.tooltip').remove();
  411. $grid.focus();
  412. });
  413. },
  414. saveEdit: function () {
  415. var $grid = $(this);
  416. var editRowId = $grid.editRowId();
  417. if (!editRowId) return $grid.getData();
  418. if (!saveEditRow.call(this)) {
  419. return false;
  420. }
  421. return $grid.getData();
  422. },
  423. lastClickCol: function (value) {
  424. var $grid = $(this);
  425. if ($.type(value) === 'undefined') {
  426. return $grid.jqGrid('getGridParam', 'lastClickCol');
  427. }
  428. return $grid.jqGrid('getGridParam').lastClickCol = value;
  429. },
  430. editRowId: function (value) {
  431. var $grid = $(this);
  432. if ($.type(value) === 'undefined') {
  433. return $grid.jqGrid('getGridParam', 'editRowId');
  434. }
  435. return $grid.jqGrid('getGridParam').editRowId = value;
  436. },
  437. editRowDataOrg: function (value) {
  438. var $grid = $(this);
  439. if ($.type(value) === 'undefined') {
  440. return $grid.jqGrid('getGridParam', 'editRowDataOrg');
  441. }
  442. return $grid.jqGrid('getGridParam').editRowDataOrg = value;
  443. },
  444. editRowData: function (value) {
  445. var $grid = $(this);
  446. if ($.type(value) === 'undefined') {
  447. return $grid.jqGrid('getGridParam', 'editRowData');
  448. }
  449. return $grid.jqGrid('getGridParam').editRowData = value;
  450. }
  451. });
  452. })(jQuery);