Note: The customer requires the following Aggregate functions under the grid:
The implementation code is as follows:
Ext. NS ('ext. UX. grid'); var DEBUG =! False; Ext. UX. grid. gridsummary = function (config) {Ext. apply (this, config) ;}; Ext. extend (ext. UX. grid. gridsummary, ext. util. observable, {init: function (GRID) {This. grid = grid; this. cm = grid. getcolumnmodel (); this. view = grid. getview (); var v = This. view; // override gridview's onlayout () method v. onlayout = This. onlayout; V. aftermethod ('render', this. refreshsummary, this); V. aftermethod ('refresh', This. refreshsummary, this); // v. aftermethod ('syncscroll ', this. syncsummaryscroll, this); V. aftermethod ('oncolumnwidthupdated', this. dowidth, this); V. aftermethod ('onallcolumnwidthsupdated', this. doallwidths, this); V. aftermethod ('oncolumnhiddenupdated', this. dohidden, this); // Update Summary row on store's Add/Remove/clear/update events grid. store. on ({Add: This. refreshsummary, remove: This. ref Reshsummary, clear: this. refreshsummary, update: This. refreshsummary, scope: This}); If (! This. rowtpl) {This. rowtpl = new Ext. template ('<Div style = "overflow-X: hidden;" class = "x-grid3-summary-row, x-grid3-gridsummary-row-offset"> ', '<Table class = "x-grid3-summary-table" border = "0" cellspacing = "0" cellpadding = "0" style = "{tstyle}"> ', '<tbody> <tr> {cells} </tr> </tbody>', '</table>', '</div>'); this. rowtpl. disableformats = true;} This. rowtpl. compile (); If (! This. celltpl) {This. celltpl = new Ext. template ('<TD class = "x-grid3-col x-grid3-cell x-grid3-td-{ID} X-selectable {CSS}" style = "{style}" tabindex = "0" {cellattr}> ', '<Div class = "x-grid3-cell-inner x-grid3-col-{ID}" {ATTR}> {value} </div>', '</TD>'); this. celltpl. disableformats = true;} This. celltpl. compile () ;}, calculate: function (RS, CM) {var data ={}, CFG = cm. config; // loop through all columns I N columnmodel for (VAR I = 0, Len = cfg. length; I <Len; I ++) {var cf = CFG [I], // get column's configuration cname = cf. dataindex; // get column dataindex // initialise grid summary row data for the current column being // worked on data [cname] = 0; If (cf. summarytype) {for (var j = 0, jlen = Rs. length; j <jlen; j ++) {var r = Rs [J]; // get a single record data [cname] = todecimal (ext. UX. grid. gr Idsummary. calculations [Cf. summarytype] (R. get (cname), R, cname, Data, j) ;}} return data ;}, onlayout: function (VW, VH) {If (ext. type (VL )! = 'Number') {// handles grid's height: 'auto' config return;} // Note: This method is scoped to the gridview if (! This. grid. getgridel (). hasclass ('x-grid-hide-gridsummary ') {// readjust gridview's height only if grid summary row is visible this. scroller. setheight (VH-this. summary. getheight () ;}, syncsummaryscroll: function () {var MB = This. view. scroller. dom; this. view. summarywrap. dom. scrollleft = Mb. scrollleft; // second time for IE (1/2 time first fails, other browsers ignore) This. view. summarywrap. dom. Scrollleft = Mb. scrollleft; // alert (this. view. summarywrap. dom. scrollleft) ;}, dowidth: function (COL, W, TW) {var S = This. view. summary. dom; S. firstchild. style. width = TW; S. firstchild. rows [0]. childnodes [col]. style. width = W ;}, doallwidths: function (WS, TW) {var S = This. view. summary. dom, WLEN = ws. length; S. firstchild. style. width = TW; var cells = S. firstchild. rows [0]. childnodes; For (var j = 0; j <WLEN; j ++) {cells [J]. style. width = ws [J] ;}}, dohidden: function (COL, hidden, TW) {var S = This. view. summary. dom, display = hidden? 'None': ''; S. firstchild. style. width = TW; S. firstchild. rows [0]. childnodes [col]. style. display = display ;}, rendersummary: function (O, Cs, CM) {cs = cs | this. view. getcolumndata (); var CFG = cm. config, Buf = [], last = cs. length-1; for (VAR I = 0, Len = cs. length; I <Len; I ++) {var c = cs [I], cf = CFG [I], P = {}; p. id = C. ID; p. style = C. style; p.css = I = 0? 'X-grid3-cell-first ': (I = last? 'X-grid3-cell-last ': ''); var DS = This. grid. store; If (cf. summarytype | cf. summaryrenderer) & Ds. gettotalcount ()> 0) {P. value = (cf. summaryrenderer | C. renderer) (O. griddata [C. name], p, O);} else {P. value = '';} If (P. value = undefined | P. value = "") p. value = ""; Buf [Buf. length] = This. celltpl. apply (p);} return this. rowtpl. apply ({tstyle: 'width: '+ this. view. gettotalwidth () + '; ', Cells: Buf. join ('')}) ;}, refreshsummary: function () {var G = This. grid, DS = G. store, cs = This. view. getcolumndata (), Cm = This. cm, RS = Ds. getrange (), data = This. calculate (RS, cm), Buf = This. rendersummary ({griddata: Data}, Cs, CM); If (! This. view. summarywrap) {This. view. summarywrap = ext. domhelper. insertafter (this. view. scroller, {Tag: 'div ', CLS: 'x-grid3-gridsummary-row-inner'}, true);} else {This. view. summary. remove ();} This. view. summary = This. view. summarywrap. update (BUF ). first (); this. view. scroller. setstyle ('overflow-x', 'den den '); var view2 = This. view; this. view. summary. setstyle ('overflow', 'auto'); // solve the problem of scroll bar and refresh the page To the initial position. This. View. Summary. Dom. scrollleft = This. View. scroller. Dom. scrollleft; // solves the problem of scroll bar and the problem of returning the page to the initial position. This. view. summary. on ("scroll", function () {view2.scroller. dom. scrollleft = view2.summary. dom. scrollleft}) ;}, togglesummary: function (visible) {// true to display summary row var El = This. grid. getgridel (); If (EL) {If (visible = undefined) {visible = el. hasclass ('x-grid-hide-gridsummary ');} El [visible? 'Removeclass ': 'addclass'] ('x-grid-hide-gridsummary'); this. view. layout (); // readjust gridview height }}, getsummarynode: function () {return this. view. summary}); Ext. reg ('gridsummary ', ext. UX. grid. gridsummary); Ext. UX. grid. gridsummary. calculations = {sum: function (v, record, colname, Data, rowidx) {return data [colname] + todecimal (ext. num (v, 0);}, Count: function (v, record, colname, Data, R Owidx) {return rowidx + 1;}, Max: function (v, record, colname, Data, rowidx) {return math. max (ext. num (v, 0), data [colname]) ;}, min: function (v, record, colname, Data, rowidx) {return math. min (ext. num (v, 0), data [colname]) ;}, average: function (v, record, colname, Data, rowidx) {var T = data [colname] + Ext. num (v, 0), Count = record. store. getcount (); Return rowidx = count-1? (T/count): T ;}, Total: function () {return "\ u5408 \ u8ba1" ;}// retain two decimal places. // function: Rounding floating point numbers, function todecimal (x) {var F = parsefloat (x); If (isnan (F) {return;} f = math. floor (x * 100)/100; return F ;}
3. Use the following code:
VaR summary = new Ext. UX. grid. gridsummary (); // declare this. gridpanel = new Ext. grid. gridpanel ({ID: "planbookallgrid", Region: "center", striperows: True, tbar: This. topbar, store: This. store, columnlines: True, width: "100%", trackmouseover: True, disableselection: false, loadmask: True, CM: A, SM: B, plugins: [this. rowactions, Summary], // Add viewconfig: {forcefit: false, enablerowbody: false, showpreview: false}, bbar: New Ht in plugins. pagingbar ({store: This. store })});
VaR A = new Ext. grid. columnmodel ({columns: [B, new Ext. grid. rownumberer ({header: "No.", width: 35}), {header: "mainid", dataindex: "mainid", hideable: false, hidden: true}, {header: "runid", dataindex: "runid", hideable: false, hidden: true}, {header: "Annual Plan Project No.", dataindex: "planprojectnu", summarytype: "Total" },{ header: "Training Course name", dataindex: "trainingclassname" },{ header: "Training Category 1", dataindex: "trainingmaintype" },{ header: "Training Category 2", dataindex: "trainingsontype" },{ header: "Training Category 3", dataindex: "traininggrandsontype" },{ header: "training start time", dataindex: "trainingstarttime", Renderer: function (V2) {return apputil. formatedate (V2) ;},{ header: "Training end time", dataindex: "trainingendtime", Renderer: function (V2) {return apputil. formatedate (V2) ;},{ header: "Monthly", dataindex: "Monthly" },{ header: "Number of classes", dataindex: "classnumber", summarytype: 'sume' // Add summarytype}, {header: "class", dataindex: "forsecastclasstime", summarytype: 'sume '},