yvanui.edatagrid.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507
  1. /**
  2. * edatagrid - jQuery EasyUI
  3. *
  4. * Licensed under the GPL:
  5. * http://www.gnu.org/licenses/gpl.txt
  6. *
  7. * Copyright 2011 stworthy [ stworthy@gmail.com ]
  8. *
  9. * Dependencies:
  10. * datagrid
  11. * messager
  12. *
  13. */
  14. (function ($) {
  15. var currTarget;
  16. $(function () {
  17. $(document).unbind('.edatagrid').bind('mousedown.edatagrid', function (e) {
  18. var p = $(e.target).closest('div.datagrid-view,div.combo-panel');
  19. if (p.length) {
  20. if (p.hasClass('datagrid-view')) {
  21. var dg = p.children('table');
  22. if (dg.length && currTarget != dg[0]) {
  23. _save();
  24. }
  25. }
  26. return;
  27. }
  28. _save();
  29. function _save() {
  30. var dg = $(currTarget);
  31. if (dg.length) {
  32. dg.edatagrid('saveRow');
  33. currTarget = undefined;
  34. }
  35. }
  36. });
  37. });
  38. function buildGrid(target) {
  39. var opts = $.data(target, 'edatagrid').options;
  40. $(target).datagrid($.extend({}, opts, {
  41. onDblClickCell: function (index, field) {
  42. if (opts.editing) {
  43. $(this).edatagrid('editRow', index);
  44. focusEditor(field);
  45. }
  46. },
  47. onBeginEdit: function (index, row) {
  48. if (shortcut) {
  49. var $dg = $(this);
  50. shortcut.processEgridEditor($dg, index, row);
  51. }
  52. },
  53. onClickCell: function (index, field) {
  54. if (opts.editing && opts.editIndex >= 0) {
  55. $(this).edatagrid('editRow', index);
  56. focusEditor(field);
  57. }
  58. },
  59. onAfterEdit: function (index, row) {
  60. opts.editIndex = -1;
  61. var url = row.isNewRecord ? opts.saveUrl : opts.updateUrl;
  62. if (url) {
  63. $.post(url, row, function (data) {
  64. if (data.isError) {
  65. $(target).edatagrid('cancelRow', index);
  66. $(target).edatagrid('selectRow', index);
  67. $(target).edatagrid('editRow', index);
  68. opts.onError.call(target, index, data);
  69. return;
  70. }
  71. data.isNewRecord = null;
  72. $(target).datagrid('updateRow', {
  73. index: index,
  74. row: data
  75. });
  76. if (opts.tree) {
  77. var idValue = row[opts.idField || 'id'];
  78. var t = $(opts.tree);
  79. var node = t.tree('find', idValue);
  80. if (node) {
  81. node.text = row[opts.treeTextField];
  82. t.tree('update', node);
  83. } else {
  84. var pnode = t.tree('find', row[opts.treeParentField]);
  85. t.tree('append', {
  86. parent: (pnode ? pnode.target : null),
  87. data: [{id: idValue, text: row[opts.treeTextField]}]
  88. });
  89. }
  90. }
  91. opts.onSave.call(target, index, row);
  92. }, 'json');
  93. } else {
  94. opts.onSave.call(target, index, row);
  95. }
  96. if (opts.onAfterEdit) opts.onAfterEdit.call(target, index, row);
  97. },
  98. onCancelEdit: function (index, row) {
  99. opts.editIndex = -1;
  100. if (row.isNewRecord) {
  101. $(this).datagrid('deleteRow', index);
  102. }
  103. if (opts.onCancelEdit) opts.onCancelEdit.call(target, index, row);
  104. },
  105. onBeforeLoad: function (param) {
  106. if (opts.onBeforeLoad.call(target, param) == false) {
  107. return false
  108. }
  109. // $(this).datagrid('rejectChanges');
  110. $(this).edatagrid('cancelRow');
  111. if (opts.tree) {
  112. var node = $(opts.tree).tree('getSelected');
  113. param[opts.treeParentField] = node ? node.id : undefined;
  114. }
  115. }
  116. }));
  117. function focusEditor(field) {
  118. var editor = $(target).datagrid('getEditor', {index: opts.editIndex, field: field});
  119. if (editor) {
  120. editor.target.focus();
  121. } else {
  122. var editors = $(target).datagrid('getEditors', opts.editIndex);
  123. if (editors.length) {
  124. editors[0].target.focus();
  125. }
  126. }
  127. }
  128. if (opts.tree) {
  129. $(opts.tree).tree({
  130. url: opts.treeUrl,
  131. onClick: function (node) {
  132. $(target).datagrid('load');
  133. },
  134. onDrop: function (dest, source, point) {
  135. var targetId = $(this).tree('getNode', dest).id;
  136. $.ajax({
  137. url: opts.treeDndUrl,
  138. type: 'post',
  139. data: {
  140. id: source.id,
  141. targetId: targetId,
  142. point: point
  143. },
  144. dataType: 'json',
  145. success: function () {
  146. $(target).datagrid('load');
  147. }
  148. });
  149. }
  150. });
  151. }
  152. }
  153. $.fn.edatagrid = function (options, param) {
  154. if (typeof options == 'string') {
  155. var method = $.fn.edatagrid.methods[options];
  156. if (method) {
  157. return method(this, param);
  158. } else {
  159. return this.datagrid(options, param);
  160. }
  161. }
  162. options = options || {};
  163. return this.each(function () {
  164. var state = $.data(this, 'edatagrid');
  165. if (state) {
  166. $.extend(state.options, options);
  167. } else {
  168. $.data(this, 'edatagrid', {
  169. options: $.extend({}, $.fn.edatagrid.defaults, $.fn.edatagrid.parseOptions(this), options)
  170. });
  171. }
  172. buildGrid(this);
  173. });
  174. };
  175. $.fn.edatagrid.parseOptions = function (target) {
  176. return $.extend({}, $.fn.datagrid.parseOptions(target), {});
  177. };
  178. $.fn.edatagrid.methods = {
  179. focusEditor: function (jq, field) {
  180. var $dg = $(jq[0]);
  181. var opts = $.data(jq[0], 'edatagrid').options;
  182. if (field) {
  183. var editor = $dg.datagrid('getEditor', {index: opts.editIndex, field: field});
  184. if (editor) {
  185. editor.target.focus();
  186. return;
  187. }
  188. }
  189. var editors = $dg.datagrid('getEditors', opts.editIndex);
  190. if (editors.length) {
  191. //editors[0].target.focus();
  192. $(editors[0].target).textbox('textbox').focus();
  193. }
  194. },
  195. validateRow: function (jq, index) {
  196. var tr = $.data(jq[0], "datagrid").options.finder.getTr(jq[0], index);
  197. if (!tr.hasClass("datagrid-row-editing")) {
  198. return true;
  199. }
  200. var vbox = tr.find(".validatebox-text");
  201. vbox.validatebox("validate");
  202. //vbox.trigger("mouseleave");
  203. var r = tr.find(".validatebox-invalid");
  204. if (r.length === 0) {
  205. return true;
  206. }
  207. $.yvan.msg('有' + r.length + '项校验未通过,请核对后再进行操作');
  208. r[0].focus();
  209. return false;
  210. },
  211. getEditRowIndex: function (jq) {
  212. var opts = $.data(jq[0], 'edatagrid').options;
  213. return opts.editIndex;
  214. },
  215. getEditRow: function (jq) {
  216. var opts = $.data(jq[0], 'edatagrid').options;
  217. if (opts.editIndex < 0) return;
  218. //获取到数据行
  219. var dg = $(jq[0]);
  220. var rows = dg.datagrid("getRows");
  221. var row = rows[opts.editIndex];
  222. //获取到编辑器
  223. var editors = dg.datagrid('getEditors', opts.editIndex);
  224. for (var i = 0; i < editors.length; i++) {
  225. var editor = editors [i];
  226. if ($.type(editor) === 'undefined') continue;
  227. if (!editor.hasOwnProperty('field')) continue;
  228. if (!editor.hasOwnProperty('type')) continue;
  229. if ($.inArray(editor.type, ['textbox', 'numberbox',
  230. 'numberspinner', 'combobox', 'combotree', 'combogrid',
  231. 'datebox', 'datetimebox', 'searchbox']) >= 0) {
  232. row[editor.field] = editor.target.textbox('getValue');
  233. } else if (editor.type === 'checkbox') {
  234. var cn = editor.target.is(':checked');
  235. if (cn === true) {
  236. row[editor.field] = editor.target.val();
  237. } else if (cn === false) {
  238. row[editor.field] = editor.target.attr('offval');
  239. } else {
  240. cn = editor.target.next().children()[0].className;
  241. if (cn === 'checkbox-inner') {
  242. row[editor.field] = editor.target.attr('offval');
  243. } else if (cn === 'checkbox-inner checkbox-checked') {
  244. row[editor.field] = editor.target.val();
  245. } else {
  246. console.error('未知的checkbox值');
  247. }
  248. }
  249. } else {
  250. console.error('未知的取值方法:' + editor.type, ', 字段名:' + editor.field);
  251. }
  252. }
  253. //填充未获取到的值
  254. var columns = dg.edatagrid('getColumnFields');
  255. for (var i = 0; i < columns.length; i++) {
  256. if (row.hasOwnProperty(columns[i])) continue;
  257. row[columns[i]] = null;
  258. }
  259. return row;
  260. },
  261. setEditRow: function (jq, data) {
  262. var opts = $.data(jq[0], 'edatagrid').options;
  263. if (opts.editIndex < 0) {
  264. $.yvan.msg('没有找到编辑行');
  265. return;
  266. }
  267. var editIndex = opts.editIndex;
  268. var dg = $(jq[0]);
  269. var rows = dg.datagrid("getRows");
  270. $.extend(rows[opts.editIndex], data);
  271. opts.editIndex = -1;
  272. setTimeout(function () {
  273. dg.edatagrid('refreshRow', editIndex);
  274. dg.edatagrid('editRow', editIndex);
  275. }, 0);
  276. },
  277. options: function (jq) {
  278. var opts = $.data(jq[0], 'edatagrid').options;
  279. return opts;
  280. },
  281. enableEditing: function (jq) {
  282. return jq.each(function () {
  283. var opts = $.data(this, 'edatagrid').options;
  284. opts.editing = true;
  285. });
  286. },
  287. disableEditing: function (jq) {
  288. return jq.each(function () {
  289. var opts = $.data(this, 'edatagrid').options;
  290. opts.editing = false;
  291. });
  292. },
  293. editRow: function (jq, index) {
  294. return jq.each(function () {
  295. var dg = $(this);
  296. var opts = $.data(this, 'edatagrid').options;
  297. var editIndex = opts.editIndex;
  298. if (editIndex != index) {
  299. if (dg.edatagrid('validateRow', editIndex)) {
  300. if (editIndex >= 0) {
  301. if (opts.onBeforeSave.call(this, editIndex) == false) {
  302. setTimeout(function () {
  303. dg.datagrid('selectRow', editIndex);
  304. }, 0);
  305. return;
  306. }
  307. }
  308. dg.datagrid('endEdit', editIndex);
  309. dg.datagrid('beginEdit', index);
  310. opts.editIndex = index;
  311. if (currTarget != this && $(currTarget).length) {
  312. $(currTarget).edatagrid('saveRow');
  313. currTarget = undefined;
  314. }
  315. if (opts.autoSave) {
  316. currTarget = this;
  317. }
  318. var rows = dg.datagrid('getRows');
  319. opts.onEdit.call(this, index, rows[index]);
  320. } else {
  321. setTimeout(function () {
  322. dg.datagrid('selectRow', editIndex);
  323. }, 0);
  324. }
  325. }
  326. });
  327. },
  328. addRow: function (jq, index) {
  329. return jq.each(function () {
  330. var dg = $(this);
  331. var opts = $.data(this, 'edatagrid').options;
  332. if (opts.editIndex >= 0) {
  333. if (!dg.edatagrid('validateRow', opts.editIndex)) {
  334. dg.datagrid('selectRow', opts.editIndex);
  335. return;
  336. }
  337. if (opts.onBeforeSave.call(this, opts.editIndex) == false) {
  338. setTimeout(function () {
  339. dg.datagrid('selectRow', opts.editIndex);
  340. }, 0);
  341. return;
  342. }
  343. dg.datagrid('endEdit', opts.editIndex);
  344. }
  345. var rows = dg.datagrid('getRows');
  346. function _add(index, row) {
  347. if (index == undefined) {
  348. dg.datagrid('appendRow', row);
  349. opts.editIndex = rows.length - 1;
  350. } else {
  351. dg.datagrid('insertRow', {index: index, row: row});
  352. opts.editIndex = index;
  353. }
  354. }
  355. if (typeof index == 'object') {
  356. _add(index.index, $.extend(index.row, {isNewRecord: true}))
  357. } else {
  358. _add(index, {isNewRecord: true});
  359. }
  360. // if (index == undefined){
  361. // dg.datagrid('appendRow', {isNewRecord:true});
  362. // opts.editIndex = rows.length - 1;
  363. // } else {
  364. // dg.datagrid('insertRow', {
  365. // index: index,
  366. // row: {isNewRecord:true}
  367. // });
  368. // opts.editIndex = index;
  369. // }
  370. dg.datagrid('beginEdit', opts.editIndex);
  371. dg.datagrid('selectRow', opts.editIndex);
  372. if (opts.tree) {
  373. var node = $(opts.tree).tree('getSelected');
  374. rows[opts.editIndex][opts.treeParentField] = (node ? node.id : 0);
  375. }
  376. opts.onAdd.call(this, opts.editIndex, rows[opts.editIndex]);
  377. });
  378. },
  379. saveRow: function (jq) {
  380. return jq.each(function () {
  381. var dg = $(this);
  382. var opts = $.data(this, 'edatagrid').options;
  383. if (opts.editIndex >= 0) {
  384. if (dg.edatagrid('validateRow', opts.editIndex)) {
  385. if (opts.onBeforeSave.call(this, opts.editIndex) === false) {
  386. setTimeout(function () {
  387. dg.datagrid('selectRow', opts.editIndex);
  388. }, 0);
  389. return;
  390. }
  391. $(this).datagrid('endEdit', opts.editIndex);
  392. }
  393. }
  394. });
  395. },
  396. save: function (jq) {
  397. var dg = $(jq[0]);
  398. dg.edatagrid('saveRow');
  399. if (dg.edatagrid('getEditRowIndex') >= 0) {
  400. return false;
  401. }
  402. return dg.datagrid('getRows');
  403. },
  404. cancelRow: function (jq) {
  405. return jq.each(function () {
  406. var opts = $.data(this, 'edatagrid').options;
  407. if (opts.editIndex >= 0) {
  408. $(this).datagrid('cancelEdit', opts.editIndex);
  409. }
  410. });
  411. },
  412. destroyRow: function (jq, index) {
  413. return jq.each(function () {
  414. var dg = $(this);
  415. var opts = $.data(this, 'edatagrid').options;
  416. var rows = [];
  417. if (index === undefined) {
  418. rows = dg.datagrid('getSelections');
  419. } else {
  420. var rowIndexes = $.isArray(index) ? index : [index];
  421. for (var i = 0; i < rowIndexes.length; i++) {
  422. var row = opts.finder.getRow(this, rowIndexes[i]);
  423. if (row) {
  424. rows.push(row);
  425. }
  426. }
  427. }
  428. for (var i = 0; i < rows.length; i++) {
  429. _del(rows[i]);
  430. }
  431. dg.datagrid('clearSelections');
  432. function _del(row) {
  433. var index = dg.datagrid('getRowIndex', row);
  434. if (index == -1) {
  435. return
  436. }
  437. if (index === opts.editIndex) {
  438. dg.datagrid('refreshRow', index);
  439. opts.editIndex = -1;
  440. }
  441. dg.datagrid('deleteRow', index);
  442. opts.onDestroy.call(dg[0], index, row);
  443. }
  444. });
  445. }
  446. };
  447. $.fn.edatagrid.defaults = $.extend({}, $.fn.datagrid.defaults, {
  448. editing: true,
  449. editIndex: -1,
  450. autoSave: false, // auto save the editing row when click out of datagrid
  451. url: null, // return the datagrid data
  452. saveUrl: null, // return the added row
  453. updateUrl: null, // return the updated row
  454. destroyUrl: null, // return {success:true}
  455. tree: null, // the tree selector
  456. treeUrl: null, // return tree data
  457. treeDndUrl: null, // to process the drag and drop operation, return {success:true}
  458. treeTextField: 'name',
  459. treeParentField: 'parentId',
  460. onAdd: function (index, row) {
  461. },
  462. onEdit: function (index, row) {
  463. },
  464. onBeforeSave: function (index) {
  465. },
  466. onSave: function (index, row) {
  467. },
  468. onDestroy: function (index, row) {
  469. },
  470. onError: function (index, row) {
  471. }
  472. });
  473. })(jQuery);