jquery.propertygrid.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  1. /**
  2. * jQuery EasyUI 1.4.2
  3. *
  4. * Copyright (c) 2009-2015 www.jeasyui.com. All rights reserved.
  5. *
  6. * Licensed under the GPL license: http://www.gnu.org/licenses/gpl.txt
  7. * To use it on other terms please contact us at 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. table.push('<table cellspacing="0" cellpadding="0" border="0" style="height:100%"><tbody>');
  129. table.push('<tr>');
  130. if ((frozen && (opts.rownumbers || opts.frozenColumns.length)) ||
  131. (!frozen && !(opts.rownumbers || opts.frozenColumns.length))){
  132. table.push('<td style="border:0;text-align:center;width:25px"><span class="datagrid-row-expander datagrid-row-collapse" style="display:inline-block;width:16px;height:16px;cursor:pointer">&nbsp;</span></td>');
  133. }
  134. table.push('<td style="border:0;">');
  135. if (!frozen){
  136. table.push('<span class="datagrid-group-title">');
  137. table.push(opts.groupFormatter.call(target, group.value, group.rows));
  138. table.push('</span>');
  139. }
  140. table.push('</td>');
  141. table.push('</tr>');
  142. table.push('</tbody></table>');
  143. table.push('</div>');
  144. table.push('<table class="datagrid-btable" cellspacing="0" cellpadding="0" border="0"><tbody>');
  145. var index = group.startIndex;
  146. for(var j=0; j<group.rows.length; j++) {
  147. var css = opts.rowStyler ? opts.rowStyler.call(target, index, group.rows[j]) : '';
  148. var classValue = '';
  149. var styleValue = '';
  150. if (typeof css == 'string'){
  151. styleValue = css;
  152. } else if (css){
  153. classValue = css['class'] || '';
  154. styleValue = css['style'] || '';
  155. }
  156. var cls = 'class="datagrid-row ' + (index % 2 && opts.striped ? 'datagrid-row-alt ' : ' ') + classValue + '"';
  157. var style = styleValue ? 'style="' + styleValue + '"' : '';
  158. var rowId = state.rowIdPrefix + '-' + (frozen?1:2) + '-' + index;
  159. table.push('<tr id="' + rowId + '" datagrid-row-index="' + index + '" ' + cls + ' ' + style + '>');
  160. table.push(this.renderRow.call(this, target, fields, frozen, index, group.rows[j]));
  161. table.push('</tr>');
  162. index++;
  163. }
  164. table.push('</tbody></table>');
  165. return table.join('');
  166. },
  167. bindEvents: function(target){
  168. var state = $.data(target, 'datagrid');
  169. var dc = state.dc;
  170. var body = dc.body1.add(dc.body2);
  171. var clickHandler = ($.data(body[0],'events')||$._data(body[0],'events')).click[0].handler;
  172. body.unbind('click').bind('click', function(e){
  173. var tt = $(e.target);
  174. var expander = tt.closest('span.datagrid-row-expander');
  175. if (expander.length){
  176. var gindex = expander.closest('div.datagrid-group').attr('group-index');
  177. if (expander.hasClass('datagrid-row-collapse')){
  178. $(target).datagrid('collapseGroup', gindex);
  179. } else {
  180. $(target).datagrid('expandGroup', gindex);
  181. }
  182. } else {
  183. clickHandler(e);
  184. }
  185. e.stopPropagation();
  186. });
  187. },
  188. onBeforeRender: function(target, rows){
  189. var state = $.data(target, 'datagrid');
  190. var opts = state.options;
  191. initCss();
  192. var groups = [];
  193. for(var i=0; i<rows.length; i++){
  194. var row = rows[i];
  195. var group = getGroup(row[opts.groupField]);
  196. if (!group){
  197. group = {
  198. value: row[opts.groupField],
  199. rows: [row]
  200. };
  201. groups.push(group);
  202. } else {
  203. group.rows.push(row);
  204. }
  205. }
  206. var index = 0;
  207. var newRows = [];
  208. for(var i=0; i<groups.length; i++){
  209. var group = groups[i];
  210. group.startIndex = index;
  211. index += group.rows.length;
  212. newRows = newRows.concat(group.rows);
  213. }
  214. state.data.rows = newRows;
  215. this.groups = groups;
  216. var that = this;
  217. setTimeout(function(){
  218. that.bindEvents(target);
  219. },0);
  220. function getGroup(value){
  221. for(var i=0; i<groups.length; i++){
  222. var group = groups[i];
  223. if (group.value == value){
  224. return group;
  225. }
  226. }
  227. return null;
  228. }
  229. function initCss(){
  230. if (!$('#datagrid-group-style').length){
  231. $('head').append(
  232. '<style id="datagrid-group-style">' +
  233. '.datagrid-group{height:25px;overflow:hidden;font-weight:bold;border-bottom:1px solid #ccc;}' +
  234. '</style>'
  235. );
  236. }
  237. }
  238. }
  239. });
  240. $.extend($.fn.datagrid.methods, {
  241. expandGroup:function(jq, groupIndex){
  242. return jq.each(function(){
  243. var view = $.data(this, 'datagrid').dc.view;
  244. var group = view.find(groupIndex!=undefined ? 'div.datagrid-group[group-index="'+groupIndex+'"]' : 'div.datagrid-group');
  245. var expander = group.find('span.datagrid-row-expander');
  246. if (expander.hasClass('datagrid-row-expand')){
  247. expander.removeClass('datagrid-row-expand').addClass('datagrid-row-collapse');
  248. group.next('table').show();
  249. }
  250. $(this).datagrid('fixRowHeight');
  251. });
  252. },
  253. collapseGroup:function(jq, groupIndex){
  254. return jq.each(function(){
  255. var view = $.data(this, 'datagrid').dc.view;
  256. var group = view.find(groupIndex!=undefined ? 'div.datagrid-group[group-index="'+groupIndex+'"]' : 'div.datagrid-group');
  257. var expander = group.find('span.datagrid-row-expander');
  258. if (expander.hasClass('datagrid-row-collapse')){
  259. expander.removeClass('datagrid-row-collapse').addClass('datagrid-row-expand');
  260. group.next('table').hide();
  261. }
  262. $(this).datagrid('fixRowHeight');
  263. });
  264. }
  265. });
  266. $.extend(groupview, {
  267. refreshGroupTitle: function(target, groupIndex){
  268. var state = $.data(target, 'datagrid');
  269. var opts = state.options;
  270. var dc = state.dc;
  271. var group = this.groups[groupIndex];
  272. var span = dc.body2.children('div.datagrid-group[group-index=' + groupIndex + ']').find('span.datagrid-group-title');
  273. span.html(opts.groupFormatter.call(target, group.value, group.rows));
  274. },
  275. insertRow: function(target, index, row){
  276. var state = $.data(target, 'datagrid');
  277. var opts = state.options;
  278. var dc = state.dc;
  279. var group = null;
  280. var groupIndex;
  281. for(var i=0; i<this.groups.length; i++){
  282. if (this.groups[i].value == row[opts.groupField]){
  283. group = this.groups[i];
  284. groupIndex = i;
  285. break;
  286. }
  287. }
  288. if (group){
  289. if (index == undefined || index == null){
  290. index = state.data.rows.length;
  291. }
  292. if (index < group.startIndex){
  293. index = group.startIndex;
  294. } else if (index > group.startIndex + group.rows.length){
  295. index = group.startIndex + group.rows.length;
  296. }
  297. $.fn.datagrid.defaults.view.insertRow.call(this, target, index, row);
  298. if (index >= group.startIndex + group.rows.length){
  299. _moveTr(index, true);
  300. _moveTr(index, false);
  301. }
  302. group.rows.splice(index - group.startIndex, 0, row);
  303. } else {
  304. group = {
  305. value: row[opts.groupField],
  306. rows: [row],
  307. startIndex: state.data.rows.length
  308. }
  309. groupIndex = this.groups.length;
  310. dc.body1.append(this.renderGroup.call(this, target, groupIndex, group, true));
  311. dc.body2.append(this.renderGroup.call(this, target, groupIndex, group, false));
  312. this.groups.push(group);
  313. state.data.rows.push(row);
  314. }
  315. this.refreshGroupTitle(target, groupIndex);
  316. function _moveTr(index,frozen){
  317. var serno = frozen?1:2;
  318. var prevTr = opts.finder.getTr(target, index-1, 'body', serno);
  319. var tr = opts.finder.getTr(target, index, 'body', serno);
  320. tr.insertAfter(prevTr);
  321. }
  322. },
  323. updateRow: function(target, index, row){
  324. var opts = $.data(target, 'datagrid').options;
  325. $.fn.datagrid.defaults.view.updateRow.call(this, target, index, row);
  326. var tb = opts.finder.getTr(target, index, 'body', 2).closest('table.datagrid-btable');
  327. var groupIndex = parseInt(tb.prev().attr('group-index'));
  328. this.refreshGroupTitle(target, groupIndex);
  329. },
  330. deleteRow: function(target, index){
  331. var state = $.data(target, 'datagrid');
  332. var opts = state.options;
  333. var dc = state.dc;
  334. var body = dc.body1.add(dc.body2);
  335. var tb = opts.finder.getTr(target, index, 'body', 2).closest('table.datagrid-btable');
  336. var groupIndex = parseInt(tb.prev().attr('group-index'));
  337. $.fn.datagrid.defaults.view.deleteRow.call(this, target, index);
  338. var group = this.groups[groupIndex];
  339. if (group.rows.length > 1){
  340. group.rows.splice(index-group.startIndex, 1);
  341. this.refreshGroupTitle(target, groupIndex);
  342. } else {
  343. body.children('div.datagrid-group[group-index='+groupIndex+']').remove();
  344. for(var i=groupIndex+1; i<this.groups.length; i++){
  345. body.children('div.datagrid-group[group-index='+i+']').attr('group-index', i-1);
  346. }
  347. this.groups.splice(groupIndex, 1);
  348. }
  349. var index = 0;
  350. for(var i=0; i<this.groups.length; i++){
  351. var group = this.groups[i];
  352. group.startIndex = index;
  353. index += group.rows.length;
  354. }
  355. }
  356. });
  357. // end of group view definition
  358. $.fn.propertygrid.defaults = $.extend({}, $.fn.datagrid.defaults, {
  359. singleSelect:true,
  360. remoteSort:false,
  361. fitColumns:true,
  362. loadMsg:'',
  363. frozenColumns:[[
  364. {field:'f',width:16,resizable:false}
  365. ]],
  366. columns:[[
  367. {field:'name',title:'Name',width:100,sortable:true},
  368. {field:'value',title:'Value',width:100,resizable:false}
  369. ]],
  370. showGroup:false,
  371. groupView:groupview,
  372. groupField:'group',
  373. groupFormatter:function(fvalue,rows){return fvalue}
  374. });
  375. })(jQuery);