grid.subgrid.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. /*jshint eqeqeq:false */
  2. /*global jQuery */
  3. (function($){
  4. /**
  5. * jqGrid extension for SubGrid Data
  6. * Tony Tomov tony@trirand.com
  7. * http://trirand.com/blog/
  8. * Dual licensed under the MIT and GPL licenses:
  9. * http://www.opensource.org/licenses/mit-license.php
  10. * http://www.gnu.org/licenses/gpl-2.0.html
  11. **/
  12. "use strict";
  13. $.jgrid.extend({
  14. setSubGrid : function () {
  15. return this.each(function (){
  16. var $t = this, cm, i,
  17. suboptions = {
  18. plusicon : "ui-icon-plus",
  19. minusicon : "ui-icon-minus",
  20. openicon: "ui-icon-carat-1-sw",
  21. expandOnLoad: false,
  22. delayOnLoad : 50,
  23. selectOnExpand : false,
  24. selectOnCollapse : false,
  25. reloadOnExpand : true
  26. };
  27. $t.p.subGridOptions = $.extend(suboptions, $t.p.subGridOptions || {});
  28. $t.p.colNames.unshift("");
  29. $t.p.colModel.unshift({name:'subgrid',width: $.jgrid.cell_width ? $t.p.subGridWidth+$t.p.cellLayout : $t.p.subGridWidth,sortable: false,resizable:false,hidedlg:true,search:false,fixed:true});
  30. cm = $t.p.subGridModel;
  31. if(cm[0]) {
  32. cm[0].align = $.extend([],cm[0].align || []);
  33. for(i=0;i<cm[0].name.length;i++) { cm[0].align[i] = cm[0].align[i] || 'left';}
  34. }
  35. });
  36. },
  37. addSubGridCell :function (pos,iRow) {
  38. var prp='',ic,sid;
  39. this.each(function(){
  40. prp = this.formatCol(pos,iRow);
  41. sid= this.p.id;
  42. ic = this.p.subGridOptions.plusicon;
  43. });
  44. return "<td role=\"gridcell\" aria-describedby=\""+sid+"_subgrid\" class=\"ui-sgcollapsed sgcollapsed\" "+prp+"><a style='cursor:pointer;'><span class='ui-icon "+ic+"'></span></a></td>";
  45. },
  46. addSubGrid : function( pos, sind ) {
  47. return this.each(function(){
  48. var ts = this;
  49. if (!ts.grid ) { return; }
  50. //-------------------------
  51. var subGridCell = function(trdiv,cell,pos)
  52. {
  53. var tddiv = $("<td align='"+ts.p.subGridModel[0].align[pos]+"'></td>").html(cell);
  54. $(trdiv).append(tddiv);
  55. };
  56. var subGridXml = function(sjxml, sbid){
  57. var tddiv, i, sgmap,
  58. dummy = $("<table cellspacing='0' cellpadding='0' border='0'><tbody></tbody></table>"),
  59. trdiv = $("<tr></tr>");
  60. for (i = 0; i<ts.p.subGridModel[0].name.length; i++) {
  61. tddiv = $("<th class='ui-state-default ui-th-subgrid ui-th-column ui-th-"+ts.p.direction+"'></th>");
  62. $(tddiv).html(ts.p.subGridModel[0].name[i]);
  63. $(tddiv).width( ts.p.subGridModel[0].width[i]);
  64. $(trdiv).append(tddiv);
  65. }
  66. $(dummy).append(trdiv);
  67. if (sjxml){
  68. sgmap = ts.p.xmlReader.subgrid;
  69. $(sgmap.root+" "+sgmap.row, sjxml).each( function(){
  70. trdiv = $("<tr class='ui-widget-content ui-subtblcell'></tr>");
  71. if(sgmap.repeatitems === true) {
  72. $(sgmap.cell,this).each( function(i) {
  73. subGridCell(trdiv, $(this).text() || '&#160;',i);
  74. });
  75. } else {
  76. var f = ts.p.subGridModel[0].mapping || ts.p.subGridModel[0].name;
  77. if (f) {
  78. for (i=0;i<f.length;i++) {
  79. subGridCell(trdiv, $(f[i],this).text() || '&#160;',i);
  80. }
  81. }
  82. }
  83. $(dummy).append(trdiv);
  84. });
  85. }
  86. var pID = $("table:first",ts.grid.bDiv).attr("id")+"_";
  87. $("#"+$.jgrid.jqID(pID+sbid)).append(dummy);
  88. ts.grid.hDiv.loading = false;
  89. $("#load_"+$.jgrid.jqID(ts.p.id)).hide();
  90. return false;
  91. };
  92. var subGridJson = function(sjxml, sbid){
  93. var tddiv,result,i,cur, sgmap,j,
  94. dummy = $("<table cellspacing='0' cellpadding='0' border='0'><tbody></tbody></table>"),
  95. trdiv = $("<tr></tr>");
  96. for (i = 0; i<ts.p.subGridModel[0].name.length; i++) {
  97. tddiv = $("<th class='ui-state-default ui-th-subgrid ui-th-column ui-th-"+ts.p.direction+"'></th>");
  98. $(tddiv).html(ts.p.subGridModel[0].name[i]);
  99. $(tddiv).width( ts.p.subGridModel[0].width[i]);
  100. $(trdiv).append(tddiv);
  101. }
  102. $(dummy).append(trdiv);
  103. if (sjxml){
  104. sgmap = ts.p.jsonReader.subgrid;
  105. result = $.jgrid.getAccessor(sjxml, sgmap.root);
  106. if ( result !== undefined ) {
  107. for (i=0;i<result.length;i++) {
  108. cur = result[i];
  109. trdiv = $("<tr class='ui-widget-content ui-subtblcell'></tr>");
  110. if(sgmap.repeatitems === true) {
  111. if(sgmap.cell) { cur=cur[sgmap.cell]; }
  112. for (j=0;j<cur.length;j++) {
  113. subGridCell(trdiv, cur[j] || '&#160;',j);
  114. }
  115. } else {
  116. var f = ts.p.subGridModel[0].mapping || ts.p.subGridModel[0].name;
  117. if(f.length) {
  118. for (j=0;j<f.length;j++) {
  119. subGridCell(trdiv, cur[f[j]] || '&#160;',j);
  120. }
  121. }
  122. }
  123. $(dummy).append(trdiv);
  124. }
  125. }
  126. }
  127. var pID = $("table:first",ts.grid.bDiv).attr("id")+"_";
  128. $("#"+$.jgrid.jqID(pID+sbid)).append(dummy);
  129. ts.grid.hDiv.loading = false;
  130. $("#load_"+$.jgrid.jqID(ts.p.id)).hide();
  131. return false;
  132. };
  133. var populatesubgrid = function( rd )
  134. {
  135. var sid,dp, i, j;
  136. sid = $(rd).attr("id");
  137. dp = {nd_: (new Date().getTime())};
  138. dp[ts.p.prmNames.subgridid]=sid;
  139. if(!ts.p.subGridModel[0]) { return false; }
  140. if(ts.p.subGridModel[0].params) {
  141. for(j=0; j < ts.p.subGridModel[0].params.length; j++) {
  142. for(i=0; i<ts.p.colModel.length; i++) {
  143. if(ts.p.colModel[i].name === ts.p.subGridModel[0].params[j]) {
  144. dp[ts.p.colModel[i].name]= $("td:eq("+i+")",rd).text().replace(/\&#160\;/ig,'');
  145. }
  146. }
  147. }
  148. }
  149. if(!ts.grid.hDiv.loading) {
  150. ts.grid.hDiv.loading = true;
  151. $("#load_"+$.jgrid.jqID(ts.p.id)).show();
  152. if(!ts.p.subgridtype) { ts.p.subgridtype = ts.p.datatype; }
  153. if($.isFunction(ts.p.subgridtype)) {
  154. ts.p.subgridtype.call(ts, dp);
  155. } else {
  156. ts.p.subgridtype = ts.p.subgridtype.toLowerCase();
  157. }
  158. switch(ts.p.subgridtype) {
  159. case "xml":
  160. case "json":
  161. $.ajax($.extend({
  162. type:ts.p.mtype,
  163. url: $.isFunction(ts.p.subGridUrl) ? ts.p.subGridUrl.call(ts, dp) : ts.p.subGridUrl,
  164. dataType:ts.p.subgridtype,
  165. data: $.isFunction(ts.p.serializeSubGridData)? ts.p.serializeSubGridData.call(ts, dp) : dp,
  166. complete: function(sxml) {
  167. if(ts.p.subgridtype === "xml") {
  168. subGridXml(sxml.responseXML, sid);
  169. } else {
  170. subGridJson($.jgrid.parse(sxml.responseText),sid);
  171. }
  172. sxml=null;
  173. }
  174. }, $.jgrid.ajaxOptions, ts.p.ajaxSubgridOptions || {}));
  175. break;
  176. }
  177. }
  178. return false;
  179. };
  180. var _id, pID,atd, nhc=0, bfsc, r;
  181. $.each(ts.p.colModel,function(){
  182. if(this.hidden === true || this.name === 'rn' || this.name === 'cb') {
  183. nhc++;
  184. }
  185. });
  186. var len = ts.rows.length, i=1;
  187. if( sind !== undefined && sind > 0) {
  188. i = sind;
  189. len = sind+1;
  190. }
  191. while(i < len) {
  192. if($(ts.rows[i]).hasClass('jqgrow')) {
  193. if(ts.p.scroll) {
  194. $(ts.rows[i].cells[pos]).unbind('click');
  195. }
  196. $(ts.rows[i].cells[pos]).bind('click', function() {
  197. var tr = $(this).parent("tr")[0];
  198. r = tr.nextSibling;
  199. if($(this).hasClass("sgcollapsed")) {
  200. pID = ts.p.id;
  201. _id = tr.id;
  202. if(ts.p.subGridOptions.reloadOnExpand === true || ( ts.p.subGridOptions.reloadOnExpand === false && !$(r).hasClass('ui-subgrid') ) ) {
  203. atd = pos >=1 ? "<td colspan='"+pos+"'>&#160;</td>":"";
  204. bfsc = $(ts).triggerHandler("jqGridSubGridBeforeExpand", [pID + "_" + _id, _id]);
  205. bfsc = (bfsc === false || bfsc === 'stop') ? false : true;
  206. if(bfsc && $.isFunction(ts.p.subGridBeforeExpand)) {
  207. bfsc = ts.p.subGridBeforeExpand.call(ts, pID+"_"+_id,_id);
  208. }
  209. if(bfsc === false) {return false;}
  210. $(tr).after( "<tr role='row' class='ui-subgrid'>"+atd+"<td class='ui-widget-content subgrid-cell'><span class='ui-icon "+ts.p.subGridOptions.openicon+"'></span></td><td colspan='"+parseInt(ts.p.colNames.length-1-nhc,10)+"' class='ui-widget-content subgrid-data'><div id="+pID+"_"+_id+" class='tablediv'></div></td></tr>" );
  211. $(ts).triggerHandler("jqGridSubGridRowExpanded", [pID + "_" + _id, _id]);
  212. if( $.isFunction(ts.p.subGridRowExpanded)) {
  213. ts.p.subGridRowExpanded.call(ts, pID+"_"+ _id,_id);
  214. } else {
  215. populatesubgrid(tr);
  216. }
  217. } else {
  218. $(r).show();
  219. }
  220. $(this).html("<a style='cursor:pointer;'><span class='ui-icon "+ts.p.subGridOptions.minusicon+"'></span></a>").removeClass("sgcollapsed").addClass("sgexpanded");
  221. if(ts.p.subGridOptions.selectOnExpand) {
  222. $(ts).jqGrid('setSelection',_id);
  223. }
  224. } else if($(this).hasClass("sgexpanded")) {
  225. bfsc = $(ts).triggerHandler("jqGridSubGridRowColapsed", [pID + "_" + _id, _id]);
  226. bfsc = (bfsc === false || bfsc === 'stop') ? false : true;
  227. _id = tr.id;
  228. if( bfsc && $.isFunction(ts.p.subGridRowColapsed)) {
  229. bfsc = ts.p.subGridRowColapsed.call(ts, pID+"_"+_id,_id );
  230. }
  231. if(bfsc===false) {return false;}
  232. if(ts.p.subGridOptions.reloadOnExpand === true) {
  233. $(r).remove(".ui-subgrid");
  234. } else if($(r).hasClass('ui-subgrid')) { // incase of dynamic deleting
  235. $(r).hide();
  236. }
  237. $(this).html("<a style='cursor:pointer;'><span class='ui-icon "+ts.p.subGridOptions.plusicon+"'></span></a>").removeClass("sgexpanded").addClass("sgcollapsed");
  238. if(ts.p.subGridOptions.selectOnCollapse) {
  239. $(ts).jqGrid('setSelection',_id);
  240. }
  241. }
  242. return false;
  243. });
  244. }
  245. i++;
  246. }
  247. if(ts.p.subGridOptions.expandOnLoad === true) {
  248. $(ts.rows).filter('.jqgrow').each(function(index,row){
  249. $(row.cells[0]).click();
  250. });
  251. }
  252. ts.subGridXml = function(xml,sid) {subGridXml(xml,sid);};
  253. ts.subGridJson = function(json,sid) {subGridJson(json,sid);};
  254. });
  255. },
  256. expandSubGridRow : function(rowid) {
  257. return this.each(function () {
  258. var $t = this;
  259. if(!$t.grid && !rowid) {return;}
  260. if($t.p.subGrid===true) {
  261. var rc = $(this).jqGrid("getInd",rowid,true);
  262. if(rc) {
  263. var sgc = $("td.sgcollapsed",rc)[0];
  264. if(sgc) {
  265. $(sgc).trigger("click");
  266. }
  267. }
  268. }
  269. });
  270. },
  271. collapseSubGridRow : function(rowid) {
  272. return this.each(function () {
  273. var $t = this;
  274. if(!$t.grid && !rowid) {return;}
  275. if($t.p.subGrid===true) {
  276. var rc = $(this).jqGrid("getInd",rowid,true);
  277. if(rc) {
  278. var sgc = $("td.sgexpanded",rc)[0];
  279. if(sgc) {
  280. $(sgc).trigger("click");
  281. }
  282. }
  283. }
  284. });
  285. },
  286. toggleSubGridRow : function(rowid) {
  287. return this.each(function () {
  288. var $t = this;
  289. if(!$t.grid && !rowid) {return;}
  290. if($t.p.subGrid===true) {
  291. var rc = $(this).jqGrid("getInd",rowid,true);
  292. if(rc) {
  293. var sgc = $("td.sgcollapsed",rc)[0];
  294. if(sgc) {
  295. $(sgc).trigger("click");
  296. } else {
  297. sgc = $("td.sgexpanded",rc)[0];
  298. if(sgc) {
  299. $(sgc).trigger("click");
  300. }
  301. }
  302. }
  303. }
  304. });
  305. }
  306. });
  307. })(jQuery);