jquery.propertygrid.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  1. /**
  2. * jQuery EasyUI 1.5.2
  3. *
  4. * Copyright (c) 2009-2017 www.jeasyui.com. All rights reserved.
  5. *
  6. * Licensed under the freeware license: http://www.jeasyui.com/license_freeware.php
  7. * To use it on other terms please contact us: info@jeasyui.com
  8. *
  9. */
  10. /**
  11. * propertygrid - jQuery EasyUI
  12. *
  13. * Dependencies:
  14. * datagrid
  15. *
  16. */
  17. (function($){
  18. var currTarget;
  19. $(document).unbind('.propertygrid').bind('mousedown.propertygrid', function(e){
  20. var p = $(e.target).closest('div.datagrid-view,div.combo-panel');
  21. if (p.length){return;}
  22. stopEditing(currTarget);
  23. currTarget = undefined;
  24. });
  25. function buildGrid(target){
  26. var state = $.data(target, 'propertygrid');
  27. var opts = $.data(target, 'propertygrid').options;
  28. $(target).datagrid($.extend({}, opts, {
  29. cls:'propertygrid',
  30. view:(opts.showGroup ? opts.groupView : opts.view),
  31. onBeforeEdit:function(index, row){
  32. if (opts.onBeforeEdit.call(target, index, row) == false){return false;}
  33. var dg = $(this);
  34. var row = dg.datagrid('getRows')[index];
  35. var col = dg.datagrid('getColumnOption', 'value');
  36. col.editor = row.editor;
  37. },
  38. onClickCell:function(index, field, value){
  39. if (currTarget != this){
  40. stopEditing(currTarget);
  41. currTarget = this;
  42. }
  43. if (opts.editIndex != index){
  44. stopEditing(currTarget);
  45. $(this).datagrid('beginEdit', index);
  46. var ed = $(this).datagrid('getEditor', {index:index,field:field});
  47. if (!ed){
  48. ed = $(this).datagrid('getEditor', {index:index,field:'value'});
  49. }
  50. if (ed){
  51. var t = $(ed.target);
  52. var input = t.data('textbox') ? t.textbox('textbox') : t;
  53. input.focus();
  54. opts.editIndex = index;
  55. }
  56. }
  57. opts.onClickCell.call(target, index, field, value);
  58. },
  59. loadFilter:function(data){
  60. stopEditing(this);
  61. return opts.loadFilter.call(this, data);
  62. }
  63. }));
  64. }
  65. function stopEditing(target){
  66. var t = $(target);
  67. if (!t.length){return}
  68. var opts = $.data(target, 'propertygrid').options;
  69. opts.finder.getTr(target, null, 'editing').each(function(){
  70. var index = parseInt($(this).attr('datagrid-row-index'));
  71. if (t.datagrid('validateRow', index)){
  72. t.datagrid('endEdit', index);
  73. } else {
  74. t.datagrid('cancelEdit', index);
  75. }
  76. });
  77. opts.editIndex = undefined;
  78. }
  79. $.fn.propertygrid = function(options, param){
  80. if (typeof options == 'string'){
  81. var method = $.fn.propertygrid.methods[options];
  82. if (method){
  83. return method(this, param);
  84. } else {
  85. return this.datagrid(options, param);
  86. }
  87. }
  88. options = options || {};
  89. return this.each(function(){
  90. var state = $.data(this, 'propertygrid');
  91. if (state){
  92. $.extend(state.options, options);
  93. } else {
  94. var opts = $.extend({}, $.fn.propertygrid.defaults, $.fn.propertygrid.parseOptions(this), options);
  95. opts.frozenColumns = $.extend(true, [], opts.frozenColumns);
  96. opts.columns = $.extend(true, [], opts.columns);
  97. $.data(this, 'propertygrid', {
  98. options: opts
  99. });
  100. }
  101. buildGrid(this);
  102. });
  103. }
  104. $.fn.propertygrid.methods = {
  105. options: function(jq){
  106. return $.data(jq[0], 'propertygrid').options;
  107. }
  108. };
  109. $.fn.propertygrid.parseOptions = function(target){
  110. return $.extend({}, $.fn.datagrid.parseOptions(target), $.parser.parseOptions(target,[{showGroup:'boolean'}]));
  111. };
  112. // the group view definition
  113. var groupview = $.extend({}, $.fn.datagrid.defaults.view, {
  114. render: function(target, container, frozen){
  115. var table = [];
  116. var groups = this.groups;
  117. for(var i=0; i<groups.length; i++){
  118. table.push(this.renderGroup.call(this, target, i, groups[i], frozen));
  119. }
  120. $(container).html(table.join(''));
  121. },
  122. renderGroup: function(target, groupIndex, group, frozen){
  123. var state = $.data(target, 'datagrid');
  124. var opts = state.options;
  125. var fields = $(target).datagrid('getColumnFields', frozen);
  126. var table = [];
  127. table.push('<div class="datagrid-group" group-index=' + groupIndex + '>');
  128. if ((frozen && (opts.rownumbers || opts.frozenColumns.length)) ||
  129. (!frozen && !(opts.rownumbers || opts.frozenColumns.length))){
  130. table.push('<span class="datagrid-group-expander">');
  131. table.push('<span class="datagrid-row-expander datagrid-row-collapse">&nbsp;</span>');
  132. table.push('</span>');
  133. }
  134. if (!frozen){
  135. table.push('<span class="datagrid-group-title">');
  136. table.push(opts.groupFormatter.call(target, group.value, group.rows));
  137. table.push('</span>');
  138. }
  139. table.push('</div>');
  140. table.push('<table class="datagrid-btable" cellspacing="0" cellpadding="0" border="0"><tbody>');
  141. var index = group.startIndex;
  142. for(var j=0; j<group.rows.length; j++) {
  143. var css = opts.rowStyler ? opts.rowStyler.call(target, index, group.rows[j]) : '';
  144. var classValue = '';
  145. var styleValue = '';
  146. if (typeof css == 'string'){
  147. styleValue = css;
  148. } else if (css){
  149. classValue = css['class'] || '';
  150. styleValue = css['style'] || '';
  151. }
  152. var cls = 'class="datagrid-row ' + (index % 2 && opts.striped ? 'datagrid-row-alt ' : ' ') + classValue + '"';
  153. var style = styleValue ? 'style="' + styleValue + '"' : '';
  154. var rowId = state.rowIdPrefix + '-' + (frozen?1:2) + '-' + index;
  155. table.push('<tr id="' + rowId + '" datagrid-row-index="' + index + '" ' + cls + ' ' + style + '>');
  156. table.push(this.renderRow.call(this, target, fields, frozen, index, group.rows[j]));
  157. table.push('</tr>');
  158. index++;
  159. }
  160. table.push('</tbody></table>');
  161. return table.join('');
  162. },
  163. bindEvents: function(target){
  164. var state = $.data(target, 'datagrid');
  165. var dc = state.dc;
  166. var body = dc.body1.add(dc.body2);
  167. var clickHandler = ($.data(body[0],'events')||$._data(body[0],'events')).click[0].handler;
  168. body.unbind('click').bind('click', function(e){
  169. var tt = $(e.target);
  170. var expander = tt.closest('span.datagrid-row-expander');
  171. if (expander.length){
  172. var gindex = expander.closest('div.datagrid-group').attr('group-index');
  173. if (expander.hasClass('datagrid-row-collapse')){
  174. $(target).datagrid('collapseGroup', gindex);
  175. } else {
  176. $(target).datagrid('expandGroup', gindex);
  177. }
  178. } else {
  179. clickHandler(e);
  180. }
  181. e.stopPropagation();
  182. });
  183. },
  184. onBeforeRender: function(target, rows){
  185. var state = $.data(target, 'datagrid');
  186. var opts = state.options;
  187. initCss();
  188. var groups = [];
  189. for(var i=0; i<rows.length; i++){
  190. var row = rows[i];
  191. var group = getGroup(row[opts.groupField]);
  192. if (!group){
  193. group = {
  194. value: row[opts.groupField],
  195. rows: [row]
  196. };
  197. groups.push(group);
  198. } else {
  199. group.rows.push(row);
  200. }
  201. }
  202. var index = 0;
  203. var newRows = [];
  204. for(var i=0; i<groups.length; i++){
  205. var group = groups[i];
  206. group.startIndex = index;
  207. index += group.rows.length;
  208. newRows = newRows.concat(group.rows);
  209. }
  210. state.data.rows = newRows;
  211. this.groups = groups;
  212. var that = this;
  213. setTimeout(function(){
  214. that.bindEvents(target);
  215. },0);
  216. function getGroup(value){
  217. for(var i=0; i<groups.length; i++){
  218. var group = groups[i];
  219. if (group.value == value){
  220. return group;
  221. }
  222. }
  223. return null;
  224. }
  225. function initCss(){
  226. if (!$('#datagrid-group-style').length){
  227. $('head').append(
  228. '<style id="datagrid-group-style">' +
  229. '.datagrid-group{height:'+opts.groupHeight+'px;overflow:hidden;font-weight:bold;border-bottom:1px solid #ccc;}' +
  230. '.datagrid-group-title,.datagrid-group-expander{display:inline-block;vertical-align:bottom;height:100%;line-height:'+opts.groupHeight+'px;padding:0 4px;}' +
  231. '.datagrid-group-expander{width:'+opts.expanderWidth+'px;text-align:center;padding:0}' +
  232. '.datagrid-row-expander{margin:'+Math.floor((opts.groupHeight-16)/2)+'px 0;display:inline-block;width:16px;height:16px;cursor:pointer}' +
  233. '</style>'
  234. );
  235. }
  236. }
  237. }
  238. });
  239. $.extend($.fn.datagrid.methods, {
  240. groups:function(jq){
  241. return jq.datagrid('options').view.groups;
  242. },
  243. expandGroup:function(jq, groupIndex){
  244. return jq.each(function(){
  245. var view = $.data(this, 'datagrid').dc.view;
  246. var group = view.find(groupIndex!=undefined ? 'div.datagrid-group[group-index="'+groupIndex+'"]' : 'div.datagrid-group');
  247. var expander = group.find('span.datagrid-row-expander');
  248. if (expander.hasClass('datagrid-row-expand')){
  249. expander.removeClass('datagrid-row-expand').addClass('datagrid-row-collapse');
  250. group.next('table').show();
  251. }
  252. $(this).datagrid('fixRowHeight');
  253. });
  254. },
  255. collapseGroup:function(jq, groupIndex){
  256. return jq.each(function(){
  257. var view = $.data(this, 'datagrid').dc.view;
  258. var group = view.find(groupIndex!=undefined ? 'div.datagrid-group[group-index="'+groupIndex+'"]' : 'div.datagrid-group');
  259. var expander = group.find('span.datagrid-row-expander');
  260. if (expander.hasClass('datagrid-row-collapse')){
  261. expander.removeClass('datagrid-row-collapse').addClass('datagrid-row-expand');
  262. group.next('table').hide();
  263. }
  264. $(this).datagrid('fixRowHeight');
  265. });
  266. }
  267. });
  268. $.extend(groupview, {
  269. refreshGroupTitle: function(target, groupIndex){
  270. var state = $.data(target, 'datagrid');
  271. var opts = state.options;
  272. var dc = state.dc;
  273. var group = this.groups[groupIndex];
  274. var span = dc.body2.children('div.datagrid-group[group-index=' + groupIndex + ']').find('span.datagrid-group-title');
  275. span.html(opts.groupFormatter.call(target, group.value, group.rows));
  276. },
  277. insertRow: function(target, index, row){
  278. var state = $.data(target, 'datagrid');
  279. var opts = state.options;
  280. var dc = state.dc;
  281. var group = null;
  282. var groupIndex;
  283. if (!state.data.rows.length){
  284. $(target).datagrid('loadData', [row]);
  285. return;
  286. }
  287. for(var i=0; i<this.groups.length; i++){
  288. if (this.groups[i].value == row[opts.groupField]){
  289. group = this.groups[i];
  290. groupIndex = i;
  291. break;
  292. }
  293. }
  294. if (group){
  295. if (index == undefined || index == null){
  296. index = state.data.rows.length;
  297. }
  298. if (index < group.startIndex){
  299. index = group.startIndex;
  300. } else if (index > group.startIndex + group.rows.length){
  301. index = group.startIndex + group.rows.length;
  302. }
  303. $.fn.datagrid.defaults.view.insertRow.call(this, target, index, row);
  304. if (index >= group.startIndex + group.rows.length){
  305. _moveTr(index, true);
  306. _moveTr(index, false);
  307. }
  308. group.rows.splice(index - group.startIndex, 0, row);
  309. } else {
  310. group = {
  311. value: row[opts.groupField],
  312. rows: [row],
  313. startIndex: state.data.rows.length
  314. }
  315. groupIndex = this.groups.length;
  316. dc.body1.append(this.renderGroup.call(this, target, groupIndex, group, true));
  317. dc.body2.append(this.renderGroup.call(this, target, groupIndex, group, false));
  318. this.groups.push(group);
  319. state.data.rows.push(row);
  320. }
  321. this.refreshGroupTitle(target, groupIndex);
  322. function _moveTr(index,frozen){
  323. var serno = frozen?1:2;
  324. var prevTr = opts.finder.getTr(target, index-1, 'body', serno);
  325. var tr = opts.finder.getTr(target, index, 'body', serno);
  326. tr.insertAfter(prevTr);
  327. }
  328. },
  329. updateRow: function(target, index, row){
  330. var opts = $.data(target, 'datagrid').options;
  331. $.fn.datagrid.defaults.view.updateRow.call(this, target, index, row);
  332. var tb = opts.finder.getTr(target, index, 'body', 2).closest('table.datagrid-btable');
  333. var groupIndex = parseInt(tb.prev().attr('group-index'));
  334. this.refreshGroupTitle(target, groupIndex);
  335. },
  336. deleteRow: function(target, index){
  337. var state = $.data(target, 'datagrid');
  338. var opts = state.options;
  339. var dc = state.dc;
  340. var body = dc.body1.add(dc.body2);
  341. var tb = opts.finder.getTr(target, index, 'body', 2).closest('table.datagrid-btable');
  342. var groupIndex = parseInt(tb.prev().attr('group-index'));
  343. $.fn.datagrid.defaults.view.deleteRow.call(this, target, index);
  344. var group = this.groups[groupIndex];
  345. if (group.rows.length > 1){
  346. group.rows.splice(index-group.startIndex, 1);
  347. this.refreshGroupTitle(target, groupIndex);
  348. } else {
  349. body.children('div.datagrid-group[group-index='+groupIndex+']').remove();
  350. for(var i=groupIndex+1; i<this.groups.length; i++){
  351. body.children('div.datagrid-group[group-index='+i+']').attr('group-index', i-1);
  352. }
  353. this.groups.splice(groupIndex, 1);
  354. }
  355. var index = 0;
  356. for(var i=0; i<this.groups.length; i++){
  357. var group = this.groups[i];
  358. group.startIndex = index;
  359. index += group.rows.length;
  360. }
  361. }
  362. });
  363. // end of group view definition
  364. $.fn.propertygrid.defaults = $.extend({}, $.fn.datagrid.defaults, {
  365. groupHeight:21,
  366. expanderWidth:16,
  367. singleSelect:true,
  368. remoteSort:false,
  369. fitColumns:true,
  370. loadMsg:'',
  371. frozenColumns:[[
  372. {field:'f',width:16,resizable:false}
  373. ]],
  374. columns:[[
  375. {field:'name',title:'Name',width:100,sortable:true},
  376. {field:'value',title:'Value',width:100,resizable:false}
  377. ]],
  378. showGroup:false,
  379. groupView:groupview,
  380. groupField:'group',
  381. groupFormatter:function(fvalue,rows){return fvalue}
  382. });
  383. })(jQuery);