datagrid-cellediting.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517
  1. (function($){
  2. $.extend($.fn.datagrid.defaults, {
  3. clickToEdit: true,
  4. dblclickToEdit: false,
  5. navHandler: {
  6. '37': function(e){
  7. var opts = $(this).datagrid('options');
  8. return navHandler.call(this, e, opts.isRtl?'right':'left');
  9. },
  10. '39': function(e){
  11. var opts = $(this).datagrid('options');
  12. return navHandler.call(this, e, opts.isRtl?'left':'right');
  13. },
  14. '38': function(e){
  15. return navHandler.call(this, e, 'up');
  16. },
  17. '40': function(e){
  18. return navHandler.call(this, e, 'down');
  19. },
  20. '13': function(e){
  21. return enterHandler.call(this, e);
  22. },
  23. '27': function(e){
  24. return escHandler.call(this, e);
  25. },
  26. '8': function(e){
  27. return clearHandler.call(this, e);
  28. },
  29. '46': function(e){
  30. return clearHandler.call(this, e);
  31. },
  32. 'keypress': function(e){
  33. if (e.metaKey || e.ctrlKey){
  34. return;
  35. }
  36. var dg = $(this);
  37. var param = dg.datagrid('cell'); // current cell information
  38. if (!param){return;}
  39. var input = dg.datagrid('input', param);
  40. if (!input){
  41. var tmp = $('<span></span>');
  42. tmp.html(String.fromCharCode(e.which));
  43. var c = tmp.text();
  44. tmp.remove();
  45. if (c){
  46. dg.datagrid('editCell', {
  47. index: param.index,
  48. field: param.field,
  49. value: c
  50. });
  51. return false;
  52. }
  53. }
  54. }
  55. },
  56. onBeforeCellEdit: function(index, field){},
  57. onCellEdit: function(index, field, value){
  58. var input = $(this).datagrid('input', {index:index, field:field});
  59. if (input){
  60. if (value != undefined){
  61. input.val(value);
  62. }
  63. }
  64. },
  65. onSelectCell: function(index, field){},
  66. onUnselectCell: function(index, field){}
  67. });
  68. function navHandler(e, dir){
  69. var dg = $(this);
  70. var param = dg.datagrid('cell');
  71. var input = dg.datagrid('input', param);
  72. if (!input){
  73. dg.datagrid('gotoCell', dir);
  74. return false;
  75. }
  76. }
  77. function enterHandler(e){
  78. var dg = $(this);
  79. var cell = dg.datagrid('cell');
  80. if (!cell){return;}
  81. var input = dg.datagrid('input', cell);
  82. if (input){
  83. if (input[0].tagName.toLowerCase() == 'textarea'){
  84. return;
  85. }
  86. endCellEdit(this, true);
  87. } else {
  88. dg.datagrid('editCell', cell);
  89. }
  90. return false;
  91. }
  92. function escHandler(e){
  93. endCellEdit(this, false);
  94. return false;
  95. }
  96. function clearHandler(e){
  97. var dg = $(this);
  98. var param = dg.datagrid('cell');
  99. if (!param){return;}
  100. var input = dg.datagrid('input', param);
  101. if (!input){
  102. dg.datagrid('editCell', {
  103. index: param.index,
  104. field: param.field,
  105. value: ''
  106. });
  107. return false;
  108. }
  109. }
  110. function getCurrCell(target){
  111. var cell = $(target).datagrid('getPanel').find('td.datagrid-row-selected');
  112. if (cell.length){
  113. return {
  114. index: parseInt(cell.closest('tr.datagrid-row').attr('datagrid-row-index')),
  115. field: cell.attr('field')
  116. };
  117. } else {
  118. return null;
  119. }
  120. }
  121. function unselectCell(target, p){
  122. var opts = $(target).datagrid('options');
  123. var cell = opts.finder.getTr(target, p.index).find('td[field="'+p.field+'"]');
  124. cell.removeClass('datagrid-row-selected');
  125. opts.onUnselectCell.call(target, p.index, p.field);
  126. }
  127. function unselectAllCells(target){
  128. var panel = $(target).datagrid('getPanel');
  129. panel.find('td.datagrid-row-selected').removeClass('datagrid-row-selected');
  130. }
  131. function selectCell(target, p){
  132. var opts = $(target).datagrid('options');
  133. if (opts.singleSelect){
  134. unselectAllCells(target);
  135. }
  136. var cell = opts.finder.getTr(target, p.index).find('td[field="'+p.field+'"]');
  137. cell.addClass('datagrid-row-selected');
  138. opts.onSelectCell.call(target, p.index, p.field);
  139. }
  140. function getSelectedCells(target){
  141. var cells = [];
  142. var panel = $(target).datagrid('getPanel');
  143. panel.find('td.datagrid-row-selected').each(function(){
  144. var td = $(this);
  145. cells.push({
  146. index: parseInt(td.closest('tr.datagrid-row').attr('datagrid-row-index')),
  147. field: td.attr('field')
  148. });
  149. });
  150. return cells;
  151. }
  152. function gotoCell(target, p){
  153. var dg = $(target);
  154. var opts = dg.datagrid('options');
  155. var panel = dg.datagrid('getPanel').focus();
  156. var cparam = dg.datagrid('cell');
  157. if (cparam){
  158. var input = dg.datagrid('input', cparam);
  159. if (input){
  160. input.focus();
  161. return;
  162. }
  163. }
  164. if (typeof p == 'object'){
  165. _go(p);
  166. return;
  167. }
  168. var cell = panel.find('td.datagrid-row-selected');
  169. if (!cell){return;}
  170. var fields = dg.datagrid('getColumnFields',true).concat(dg.datagrid('getColumnFields'));
  171. var field = cell.attr('field');
  172. var tr = cell.closest('tr.datagrid-row');
  173. var rowIndex = parseInt(tr.attr('datagrid-row-index'));
  174. var colIndex = $.inArray(field, fields);
  175. if (p == 'up' && rowIndex > 0){
  176. rowIndex--;
  177. } else if (p == 'down'){
  178. if (opts.finder.getRow(target, rowIndex+1)){
  179. rowIndex++;
  180. }
  181. } else if (p == 'left'){
  182. var i = colIndex - 1;
  183. while(i >= 0){
  184. var col = dg.datagrid('getColumnOption', fields[i]);
  185. if (!col.hidden){
  186. colIndex = i;
  187. break;
  188. }
  189. i--;
  190. }
  191. } else if (p == 'right'){
  192. var i = colIndex + 1;
  193. while(i <= fields.length-1){
  194. var col = dg.datagrid('getColumnOption', fields[i]);
  195. if (!col.hidden){
  196. colIndex = i;
  197. break;
  198. }
  199. i++;
  200. }
  201. }
  202. field = fields[colIndex];
  203. _go({index:rowIndex, field:field});
  204. function _go(p){
  205. dg.datagrid('scrollTo', p.index);
  206. unselectAllCells(target);
  207. selectCell(target, p);
  208. var td = opts.finder.getTr(target, p.index, 'body', 2).find('td[field="'+p.field+'"]');
  209. if (td.length){
  210. var body2 = dg.data('datagrid').dc.body2;
  211. var left = td.position().left;
  212. if (left < 0){
  213. body2._scrollLeft(body2._scrollLeft() + left*(opts.isRtl?-1:1));
  214. } else if (left+td._outerWidth()>body2.width()){
  215. body2._scrollLeft(body2._scrollLeft() + (left+td._outerWidth()-body2.width())*(opts.isRtl?-1:1));
  216. }
  217. }
  218. }
  219. }
  220. // end the current cell editing
  221. function endCellEdit(target, accepted){
  222. var dg = $(target);
  223. var cell = dg.datagrid('cell');
  224. if (cell){
  225. var input = dg.datagrid('input', cell);
  226. if (input){
  227. if (accepted){
  228. if (dg.datagrid('validateRow', cell.index)){
  229. dg.datagrid('endEdit', cell.index);
  230. dg.datagrid('gotoCell', cell);
  231. } else {
  232. dg.datagrid('gotoCell', cell);
  233. input.focus();
  234. return false;
  235. }
  236. } else {
  237. dg.datagrid('cancelEdit', cell.index);
  238. dg.datagrid('gotoCell', cell);
  239. }
  240. }
  241. }
  242. return true;
  243. }
  244. function editCell(target, param){
  245. var dg = $(target);
  246. var opts = dg.datagrid('options');
  247. var input = dg.datagrid('input', param);
  248. if (input){
  249. dg.datagrid('gotoCell', param);
  250. input.focus();
  251. return;
  252. }
  253. if (!endCellEdit(target, true)){return;}
  254. if (opts.onBeforeCellEdit.call(target, param.index, param.field) == false){
  255. return;
  256. }
  257. var fields = dg.datagrid('getColumnFields',true).concat(dg.datagrid('getColumnFields'));
  258. $.map(fields, function(field){
  259. var col = dg.datagrid('getColumnOption', field);
  260. col.editor1 = col.editor;
  261. if (field != param.field){
  262. col.editor = null;
  263. }
  264. });
  265. var col = dg.datagrid('getColumnOption', param.field);
  266. if (col.editor){
  267. dg.datagrid('beginEdit', param.index);
  268. var input = dg.datagrid('input', param);
  269. if (input){
  270. dg.datagrid('gotoCell', param);
  271. setTimeout(function(){
  272. input.unbind('.cellediting').bind('keydown.cellediting', function(e){
  273. if (e.keyCode == 13){
  274. return opts.navHandler['13'].call(target, e);
  275. // return false;
  276. }
  277. });
  278. input.focus();
  279. }, 0);
  280. opts.onCellEdit.call(target, param.index, param.field, param.value);
  281. } else {
  282. dg.datagrid('cancelEdit', param.index);
  283. dg.datagrid('gotoCell', param);
  284. }
  285. } else {
  286. dg.datagrid('gotoCell', param);
  287. }
  288. $.map(fields, function(field){
  289. var col = dg.datagrid('getColumnOption', field);
  290. col.editor = col.editor1;
  291. });
  292. }
  293. function enableCellSelecting(target){
  294. var dg = $(target);
  295. var state = dg.data('datagrid');
  296. var panel = dg.datagrid('getPanel');
  297. var opts = state.options;
  298. var dc = state.dc;
  299. panel.attr('tabindex',1).css('outline-style','none').unbind('.cellediting').bind('keydown.cellediting', function(e){
  300. var h = opts.navHandler[e.keyCode];
  301. if (h){
  302. return h.call(target, e);
  303. }
  304. });
  305. dc.body1.add(dc.body2).unbind('.cellediting').bind('click.cellediting', function(e){
  306. var tr = $(e.target).closest('.datagrid-row');
  307. if (tr.length && tr.parent().length){
  308. var td = $(e.target).closest('td[field]', tr);
  309. if (td.length){
  310. var index = parseInt(tr.attr('datagrid-row-index'));
  311. var field = td.attr('field');
  312. var p = {
  313. index: index,
  314. field: field
  315. };
  316. if (opts.singleSelect){
  317. selectCell(target, p);
  318. } else {
  319. if (opts.ctrlSelect){
  320. if (e.ctrlKey){
  321. if (td.hasClass('datagrid-row-selected')){
  322. unselectCell(target, p);
  323. } else {
  324. selectCell(target, p);
  325. }
  326. } else {
  327. unselectAllCells(target);
  328. selectCell(target, p);
  329. }
  330. } else {
  331. if (td.hasClass('datagrid-row-selected')){
  332. unselectCell(target, p);
  333. } else {
  334. selectCell(target, p);
  335. }
  336. }
  337. }
  338. }
  339. }
  340. }).bind('mouseover.cellediting', function(e){
  341. var td = $(e.target).closest('td[field]');
  342. if (td.length){
  343. td.addClass('datagrid-row-over');
  344. td.closest('tr.datagrid-row').removeClass('datagrid-row-over');
  345. }
  346. }).bind('mouseout.cellediting', function(e){
  347. var td = $(e.target).closest('td[field]');
  348. td.removeClass('datagrid-row-over');
  349. });
  350. opts.isRtl = dg.datagrid('getPanel').css('direction').toLowerCase()=='rtl';
  351. opts.OldOnBeforeSelect = opts.onBeforeSelect;
  352. opts.onBeforeSelect = function(){
  353. return false;
  354. };
  355. dg.datagrid('clearSelections');
  356. }
  357. function disableCellSelecting(target){
  358. var dg = $(target);
  359. var state = dg.data('datagrid');
  360. var panel = dg.datagrid('getPanel');
  361. var opts = state.options;
  362. opts.onBeforeSelect = opts.OldOnBeforeSelect || opts.onBeforeSelect;
  363. panel.unbind('.cellediting').find('td.datagrid-row-selected').removeClass('datagrid-row-selected');
  364. var dc = state.dc;
  365. dc.body1.add(dc.body2).unbind('.cellediting');
  366. }
  367. function enableCellEditing(target){
  368. var dg = $(target);
  369. var opts = dg.datagrid('options');
  370. var panel = dg.datagrid('getPanel');
  371. panel.attr('tabindex',1).css('outline-style','none').unbind('.cellediting').bind('keydown.cellediting', function(e){
  372. var h = opts.navHandler[e.keyCode];
  373. if (h){
  374. return h.call(target, e);
  375. }
  376. }).bind('keypress.cellediting', function(e){
  377. return opts.navHandler['keypress'].call(target, e);
  378. });
  379. panel.panel('panel').unbind('.cellediting').bind('keydown.cellediting', function(e){
  380. e.stopPropagation();
  381. }).bind('keypress.cellediting', function(e){
  382. e.stopPropagation();
  383. }).bind('mouseover.cellediting', function(e){
  384. var td = $(e.target).closest('td[field]');
  385. if (td.length){
  386. td.addClass('datagrid-row-over');
  387. td.closest('tr.datagrid-row').removeClass('datagrid-row-over');
  388. }
  389. }).bind('mouseout.cellediting', function(e){
  390. var td = $(e.target).closest('td[field]');
  391. td.removeClass('datagrid-row-over');
  392. });
  393. opts.isRtl = dg.datagrid('getPanel').css('direction').toLowerCase()=='rtl';
  394. opts.oldOnClickCell = opts.onClickCell;
  395. opts.oldOnDblClickCell = opts.onDblClickCell;
  396. opts.onClickCell = function(index, field, value){
  397. if (opts.clickToEdit){
  398. $(this).datagrid('editCell', {index:index,field:field});
  399. } else {
  400. if (endCellEdit(this, true)){
  401. $(this).datagrid('gotoCell', {
  402. index: index,
  403. field: field
  404. });
  405. }
  406. }
  407. opts.oldOnClickCell.call(this, index, field, value);
  408. }
  409. if (opts.dblclickToEdit){
  410. opts.onDblClickCell = function(index, field, value){
  411. $(this).datagrid('editCell', {index:index,field:field});
  412. opts.oldOnDblClickCell.call(this, index, field, value);
  413. }
  414. }
  415. opts.OldOnBeforeSelect = opts.onBeforeSelect;
  416. opts.onBeforeSelect = function(){
  417. return false;
  418. };
  419. dg.datagrid('clearSelections')
  420. }
  421. function disableCellEditing(target){
  422. var dg = $(target);
  423. var panel = dg.datagrid('getPanel');
  424. var opts = dg.datagrid('options');
  425. opts.onClickCell = opts.oldOnClickCell || opts.onClickCell;
  426. opts.onDblClickCell = opts.oldOnDblClickCell || opts.onDblClickCell;
  427. opts.onBeforeSelect = opts.OldOnBeforeSelect || opts.onBeforeSelect;
  428. panel.unbind('.cellediting').find('td.datagrid-row-selected').removeClass('datagrid-row-selected');
  429. panel.panel('panel').unbind('.cellediting');
  430. }
  431. $.extend($.fn.datagrid.methods, {
  432. editCell: function(jq, param){
  433. return jq.each(function(){
  434. editCell(this, param);
  435. });
  436. },
  437. isEditing: function(jq, index){
  438. var opts = $.data(jq[0], 'datagrid').options;
  439. var tr = opts.finder.getTr(jq[0], index);
  440. return tr.length && tr.hasClass('datagrid-row-editing');
  441. },
  442. gotoCell: function(jq, param){
  443. return jq.each(function(){
  444. gotoCell(this, param);
  445. });
  446. },
  447. enableCellEditing: function(jq){
  448. return jq.each(function(){
  449. enableCellEditing(this);
  450. });
  451. },
  452. disableCellEditing: function(jq){
  453. return jq.each(function(){
  454. disableCellEditing(this);
  455. });
  456. },
  457. enableCellSelecting: function(jq){
  458. return jq.each(function(){
  459. enableCellSelecting(this);
  460. });
  461. },
  462. disableCellSelecting: function(jq){
  463. return jq.each(function(){
  464. disableCellSelecting(this);
  465. });
  466. },
  467. input: function(jq, param){
  468. if (!param){return null;}
  469. var ed = jq.datagrid('getEditor', param);
  470. if (ed){
  471. var t = $(ed.target);
  472. if (t.hasClass('textbox-f')){
  473. t = t.textbox('textbox');
  474. }
  475. return t;
  476. } else {
  477. return null;
  478. }
  479. },
  480. cell: function(jq){ // get current cell info {index,field}
  481. return getCurrCell(jq[0]);
  482. },
  483. getSelectedCells: function(jq){
  484. return getSelectedCells(jq[0]);
  485. }
  486. });
  487. })(jQuery);