LockingGridView.js
上传用户:dawnssy
上传日期:2022-08-06
资源大小:9345k
文件大小:29k
源码类别:

JavaScript

开发平台:

JavaScript

  1. /*!  * Ext JS Library 3.1.0  * Copyright(c) 2006-2009 Ext JS, LLC  * licensing@extjs.com  * http://www.extjs.com/license  */ Ext.ns('Ext.ux.grid');
  2. Ext.ux.grid.LockingGridView = Ext.extend(Ext.grid.GridView, {
  3.     lockText : 'Lock',
  4.     unlockText : 'Unlock',
  5.     rowBorderWidth : 1,
  6.     lockedBorderWidth : 1,
  7.     /*
  8.      * This option ensures that height between the rows is synchronized
  9.      * between the locked and unlocked sides. This option only needs to be used
  10.      * when the row heights isn't predictable.
  11.      */
  12.     syncHeights: false,
  13.     initTemplates : function(){
  14.         var ts = this.templates || {};
  15.         if(!ts.master){
  16.             ts.master = new Ext.Template(
  17.                 '<div class="x-grid3" hidefocus="true">',
  18.                     '<div class="x-grid3-locked">',
  19.                         '<div class="x-grid3-header"><div class="x-grid3-header-inner"><div class="x-grid3-header-offset" style="{lstyle}">{lockedHeader}</div></div><div class="x-clear"></div></div>',
  20.                         '<div class="x-grid3-scroller"><div class="x-grid3-body" style="{lstyle}">{lockedBody}</div><div class="x-grid3-scroll-spacer"></div></div>',
  21.                     '</div>',
  22.                     '<div class="x-grid3-viewport x-grid3-unlocked">',
  23.                         '<div class="x-grid3-header"><div class="x-grid3-header-inner"><div class="x-grid3-header-offset" style="{ostyle}">{header}</div></div><div class="x-clear"></div></div>',
  24.                         '<div class="x-grid3-scroller"><div class="x-grid3-body" style="{bstyle}">{body}</div><a href="#" class="x-grid3-focus" tabIndex="-1"></a></div>',
  25.                     '</div>',
  26.                     '<div class="x-grid3-resize-marker">&#160;</div>',
  27.                     '<div class="x-grid3-resize-proxy">&#160;</div>',
  28.                 '</div>'
  29.             );
  30.         }
  31.         this.templates = ts;
  32.         Ext.ux.grid.LockingGridView.superclass.initTemplates.call(this);
  33.     },
  34.     getEditorParent : function(ed){
  35.         return this.el.dom;
  36.     },
  37.     initElements : function(){
  38.         var E = Ext.Element;
  39.         var el = this.grid.getGridEl().dom.firstChild;
  40.         var cs = el.childNodes;
  41.         this.el = new E(el);
  42.         this.lockedWrap = new E(cs[0]);
  43.         this.lockedHd = new E(this.lockedWrap.dom.firstChild);
  44.         this.lockedInnerHd = this.lockedHd.dom.firstChild;
  45.         this.lockedScroller = new E(this.lockedWrap.dom.childNodes[1]);
  46.         this.lockedBody = new E(this.lockedScroller.dom.firstChild);
  47.         this.mainWrap = new E(cs[1]);
  48.         this.mainHd = new E(this.mainWrap.dom.firstChild);
  49.         if(this.grid.hideHeaders){
  50.             this.lockedHd.setDisplayed(false);
  51.             this.mainHd.setDisplayed(false);
  52.         }
  53.         this.innerHd = this.mainHd.dom.firstChild;
  54.         this.scroller = new E(this.mainWrap.dom.childNodes[1]);
  55.         if(this.forceFit){
  56.             this.scroller.setStyle('overflow-x', 'hidden');
  57.         }
  58.         this.mainBody = new E(this.scroller.dom.firstChild);
  59.         this.focusEl = new E(this.scroller.dom.childNodes[1]);
  60.         this.focusEl.swallowEvent('click', true);
  61.         this.resizeMarker = new E(cs[2]);
  62.         this.resizeProxy = new E(cs[3]);
  63.     },
  64.     
  65.     getLockedRows : function(){
  66.         return this.hasRows() ? this.lockedBody.dom.childNodes : [];
  67.     },
  68.     
  69.     getLockedRow : function(row){
  70.         return this.getLockedRows()[row];
  71.     },
  72.     
  73.     getCell : function(row, col){
  74.         var llen = this.cm.getLockedCount();
  75.         if(col < llen){
  76.             return this.getLockedRow(row).getElementsByTagName('td')[col];
  77.         }
  78.         return Ext.ux.grid.LockingGridView.superclass.getCell.call(this, row, col - llen);
  79.     },
  80.     
  81.     getHeaderCell : function(index){
  82.         var llen = this.cm.getLockedCount();
  83.         if(index < llen){
  84.             return this.lockedHd.dom.getElementsByTagName('td')[index];
  85.         }
  86.         return Ext.ux.grid.LockingGridView.superclass.getHeaderCell.call(this, index - llen);
  87.     },
  88.     
  89.     addRowClass : function(row, cls){
  90.         var r = this.getLockedRow(row);
  91.         if(r){
  92.             this.fly(r).addClass(cls);
  93.         }
  94.         Ext.ux.grid.LockingGridView.superclass.addRowClass.call(this, row, cls);
  95.     },
  96.     
  97.     removeRowClass : function(row, cls){
  98.         var r = this.getLockedRow(row);
  99.         if(r){
  100.             this.fly(r).removeClass(cls);
  101.         }
  102.         Ext.ux.grid.LockingGridView.superclass.removeRowClass.call(this, row, cls);
  103.     },
  104.     
  105.     removeRow : function(row) {
  106.         Ext.removeNode(this.getLockedRow(row));
  107.         Ext.ux.grid.LockingGridView.superclass.removeRow.call(this, row);
  108.     },
  109.     
  110.     removeRows : function(firstRow, lastRow){
  111.         var bd = this.lockedBody.dom;
  112.         for(var rowIndex = firstRow; rowIndex <= lastRow; rowIndex++){
  113.             Ext.removeNode(bd.childNodes[firstRow]);
  114.         }
  115.         Ext.ux.grid.LockingGridView.superclass.removeRows.call(this, firstRow, lastRow);
  116.     },
  117.     
  118.     syncScroll : function(e){
  119.         var mb = this.scroller.dom;
  120.         this.lockedScroller.dom.scrollTop = mb.scrollTop;
  121.         Ext.ux.grid.LockingGridView.superclass.syncScroll.call(this, e);
  122.     },
  123.     
  124.     updateSortIcon : function(col, dir){
  125.         var sc = this.sortClasses,
  126.             lhds = this.lockedHd.select('td').removeClass(sc),
  127.             hds = this.mainHd.select('td').removeClass(sc),
  128.             llen = this.cm.getLockedCount(),
  129.             cls = sc[dir == 'DESC' ? 1 : 0];
  130.         if(col < llen){
  131.             lhds.item(col).addClass(cls);
  132.         }else{
  133.             hds.item(col - llen).addClass(cls);
  134.         }
  135.     },
  136.     
  137.     updateAllColumnWidths : function(){
  138.         var tw = this.getTotalWidth(),
  139.             clen = this.cm.getColumnCount(),
  140.             lw = this.getLockedWidth(),
  141.             llen = this.cm.getLockedCount(),
  142.             ws = [], len, i;
  143.         this.updateLockedWidth();
  144.         for(i = 0; i < clen; i++){
  145.             ws[i] = this.getColumnWidth(i);
  146.             var hd = this.getHeaderCell(i);
  147.             hd.style.width = ws[i];
  148.         }
  149.         var lns = this.getLockedRows(), ns = this.getRows(), row, trow, j;
  150.         for(i = 0, len = ns.length; i < len; i++){
  151.             row = lns[i];
  152.             row.style.width = lw;
  153.             if(row.firstChild){
  154.                 row.firstChild.style.width = lw;
  155.                 trow = row.firstChild.rows[0];
  156.                 for (j = 0; j < llen; j++) {
  157.                    trow.childNodes[j].style.width = ws[j];
  158.                 }
  159.             }
  160.             row = ns[i];
  161.             row.style.width = tw;
  162.             if(row.firstChild){
  163.                 row.firstChild.style.width = tw;
  164.                 trow = row.firstChild.rows[0];
  165.                 for (j = llen; j < clen; j++) {
  166.                    trow.childNodes[j - llen].style.width = ws[j];
  167.                 }
  168.             }
  169.         }
  170.         this.onAllColumnWidthsUpdated(ws, tw);
  171.         this.syncHeaderHeight();
  172.     },
  173.     
  174.     updateColumnWidth : function(col, width){
  175.         var w = this.getColumnWidth(col),
  176.             llen = this.cm.getLockedCount(),
  177.             ns, rw, c, row;
  178.         this.updateLockedWidth();
  179.         if(col < llen){
  180.             ns = this.getLockedRows();
  181.             rw = this.getLockedWidth();
  182.             c = col;
  183.         }else{
  184.             ns = this.getRows();
  185.             rw = this.getTotalWidth();
  186.             c = col - llen;
  187.         }
  188.         var hd = this.getHeaderCell(col);
  189.         hd.style.width = w;
  190.         for(var i = 0, len = ns.length; i < len; i++){
  191.             row = ns[i];
  192.             row.style.width = rw;
  193.             if(row.firstChild){
  194.                 row.firstChild.style.width = rw;
  195.                 row.firstChild.rows[0].childNodes[c].style.width = w;
  196.             }
  197.         }
  198.         this.onColumnWidthUpdated(col, w, this.getTotalWidth());
  199.         this.syncHeaderHeight();
  200.     },
  201.     
  202.     updateColumnHidden : function(col, hidden){
  203.         var llen = this.cm.getLockedCount(),
  204.             ns, rw, c, row,
  205.             display = hidden ? 'none' : '';
  206.         this.updateLockedWidth();
  207.         if(col < llen){
  208.             ns = this.getLockedRows();
  209.             rw = this.getLockedWidth();
  210.             c = col;
  211.         }else{
  212.             ns = this.getRows();
  213.             rw = this.getTotalWidth();
  214.             c = col - llen;
  215.         }
  216.         var hd = this.getHeaderCell(col);
  217.         hd.style.display = display;
  218.         for(var i = 0, len = ns.length; i < len; i++){
  219.             row = ns[i];
  220.             row.style.width = rw;
  221.             if(row.firstChild){
  222.                 row.firstChild.style.width = rw;
  223.                 row.firstChild.rows[0].childNodes[c].style.display = display;
  224.             }
  225.         }
  226.         this.onColumnHiddenUpdated(col, hidden, this.getTotalWidth());
  227.         delete this.lastViewWidth;
  228.         this.layout();
  229.     },
  230.     
  231.     doRender : function(cs, rs, ds, startRow, colCount, stripe){
  232.         var ts = this.templates, ct = ts.cell, rt = ts.row, last = colCount-1,
  233.             tstyle = 'width:'+this.getTotalWidth()+';',
  234.             lstyle = 'width:'+this.getLockedWidth()+';',
  235.             buf = [], lbuf = [], cb, lcb, c, p = {}, rp = {}, r;
  236.         for(var j = 0, len = rs.length; j < len; j++){
  237.             r = rs[j]; cb = []; lcb = [];
  238.             var rowIndex = (j+startRow);
  239.             for(var i = 0; i < colCount; i++){
  240.                 c = cs[i];
  241.                 p.id = c.id;
  242.                 p.css = (i === 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '')) +
  243.                     (this.cm.config[i].cellCls ? ' ' + this.cm.config[i].cellCls : '');
  244.                 p.attr = p.cellAttr = '';
  245.                 p.value = c.renderer(r.data[c.name], p, r, rowIndex, i, ds);
  246.                 p.style = c.style;
  247.                 if(Ext.isEmpty(p.value)){
  248.                     p.value = '&#160;';
  249.                 }
  250.                 if(this.markDirty && r.dirty && Ext.isDefined(r.modified[c.name])){
  251.                     p.css += ' x-grid3-dirty-cell';
  252.                 }
  253.                 if(c.locked){
  254.                     lcb[lcb.length] = ct.apply(p);
  255.                 }else{
  256.                     cb[cb.length] = ct.apply(p);
  257.                 }
  258.             }
  259.             var alt = [];
  260.             if(stripe && ((rowIndex+1) % 2 === 0)){
  261.                 alt[0] = 'x-grid3-row-alt';
  262.             }
  263.             if(r.dirty){
  264.                 alt[1] = ' x-grid3-dirty-row';
  265.             }
  266.             rp.cols = colCount;
  267.             if(this.getRowClass){
  268.                 alt[2] = this.getRowClass(r, rowIndex, rp, ds);
  269.             }
  270.             rp.alt = alt.join(' ');
  271.             rp.cells = cb.join('');
  272.             rp.tstyle = tstyle;
  273.             buf[buf.length] = rt.apply(rp);
  274.             rp.cells = lcb.join('');
  275.             rp.tstyle = lstyle;
  276.             lbuf[lbuf.length] = rt.apply(rp);
  277.         }
  278.         return [buf.join(''), lbuf.join('')];
  279.     },
  280.     processRows : function(startRow, skipStripe){
  281.         if(!this.ds || this.ds.getCount() < 1){
  282.             return;
  283.         }
  284.         var rows = this.getRows(),
  285.             lrows = this.getLockedRows(),
  286.             row, lrow;
  287.         skipStripe = skipStripe || !this.grid.stripeRows;
  288.         startRow = startRow || 0;
  289.         for(var i = 0, len = rows.length; i < len; ++i){
  290.             row = rows[i];
  291.             lrow = lrows[i];
  292.             row.rowIndex = i;
  293.             lrow.rowIndex = i;
  294.             if(!skipStripe){
  295.                 row.className = row.className.replace(this.rowClsRe, ' ');
  296.                 lrow.className = lrow.className.replace(this.rowClsRe, ' ');
  297.                 if ((idx + 1) % 2 === 0){
  298.                     row.className += ' x-grid3-row-alt';
  299.                     lrow.className += ' x-grid3-row-alt';
  300.                 }
  301.             }
  302.             if(this.syncHeights){
  303.                 var el1 = Ext.get(row),
  304.                     el2 = Ext.get(lrow),
  305.                     h1 = el1.getHeight(),
  306.                     h2 = el2.getHeight();
  307.                 
  308.                 if(h1 > h2){
  309.                     el2.setHeight(h1);    
  310.                 }else if(h2 > h1){
  311.                     el1.setHeight(h2);
  312.                 }
  313.             }
  314.         }
  315.         if(startRow === 0){
  316.             Ext.fly(rows[0]).addClass(this.firstRowCls);
  317.             Ext.fly(lrows[0]).addClass(this.firstRowCls);
  318.         }
  319.         Ext.fly(rows[rows.length - 1]).addClass(this.lastRowCls);
  320.         Ext.fly(lrows[lrows.length - 1]).addClass(this.lastRowCls);
  321.     },
  322.     
  323.     afterRender : function(){
  324.         if(!this.ds || !this.cm){
  325.             return;
  326.         }
  327.         var bd = this.renderRows() || ['&#160;', '&#160;'];
  328.         this.mainBody.dom.innerHTML = bd[0];
  329.         this.lockedBody.dom.innerHTML = bd[1];
  330.         this.processRows(0, true);
  331.         if(this.deferEmptyText !== true){
  332.             this.applyEmptyText();
  333.         }
  334.     },
  335.     
  336.     renderUI : function(){
  337.         var header = this.renderHeaders();
  338.         var body = this.templates.body.apply({rows:'&#160;'});
  339.         var html = this.templates.master.apply({
  340.             body: body,
  341.             header: header[0],
  342.             ostyle: 'width:'+this.getOffsetWidth()+';',
  343.             bstyle: 'width:'+this.getTotalWidth()+';',
  344.             lockedBody: body,
  345.             lockedHeader: header[1],
  346.             lstyle: 'width:'+this.getLockedWidth()+';'
  347.         });
  348.         var g = this.grid;
  349.         g.getGridEl().dom.innerHTML = html;
  350.         this.initElements();
  351.         Ext.fly(this.innerHd).on('click', this.handleHdDown, this);
  352.         Ext.fly(this.lockedInnerHd).on('click', this.handleHdDown, this);
  353.         this.mainHd.on({
  354.             scope: this,
  355.             mouseover: this.handleHdOver,
  356.             mouseout: this.handleHdOut,
  357.             mousemove: this.handleHdMove
  358.         });
  359.         this.lockedHd.on({
  360.             scope: this,
  361.             mouseover: this.handleHdOver,
  362.             mouseout: this.handleHdOut,
  363.             mousemove: this.handleHdMove
  364.         });
  365.         this.scroller.on('scroll', this.syncScroll,  this);
  366.         if(g.enableColumnResize !== false){
  367.             this.splitZone = new Ext.grid.GridView.SplitDragZone(g, this.mainHd.dom);
  368.             this.splitZone.setOuterHandleElId(Ext.id(this.lockedHd.dom));
  369.             this.splitZone.setOuterHandleElId(Ext.id(this.mainHd.dom));
  370.         }
  371.         if(g.enableColumnMove){
  372.             this.columnDrag = new Ext.grid.GridView.ColumnDragZone(g, this.innerHd);
  373.             this.columnDrag.setOuterHandleElId(Ext.id(this.lockedInnerHd));
  374.             this.columnDrag.setOuterHandleElId(Ext.id(this.innerHd));
  375.             this.columnDrop = new Ext.grid.HeaderDropZone(g, this.mainHd.dom);
  376.         }
  377.         if(g.enableHdMenu !== false){
  378.             this.hmenu = new Ext.menu.Menu({id: g.id + '-hctx'});
  379.             this.hmenu.add(
  380.                 {itemId: 'asc', text: this.sortAscText, cls: 'xg-hmenu-sort-asc'},
  381.                 {itemId: 'desc', text: this.sortDescText, cls: 'xg-hmenu-sort-desc'}
  382.             );
  383.             if(this.grid.enableColLock !== false){
  384.                 this.hmenu.add('-',
  385.                     {itemId: 'lock', text: this.lockText, cls: 'xg-hmenu-lock'},
  386.                     {itemId: 'unlock', text: this.unlockText, cls: 'xg-hmenu-unlock'}
  387.                 );
  388.             }
  389.             if(g.enableColumnHide !== false){
  390.                 this.colMenu = new Ext.menu.Menu({id:g.id + '-hcols-menu'});
  391.                 this.colMenu.on({
  392.                     scope: this,
  393.                     beforeshow: this.beforeColMenuShow,
  394.                     itemclick: this.handleHdMenuClick
  395.                 });
  396.                 this.hmenu.add('-', {
  397.                     itemId:'columns',
  398.                     hideOnClick: false,
  399.                     text: this.columnsText,
  400.                     menu: this.colMenu,
  401.                     iconCls: 'x-cols-icon'
  402.                 });
  403.             }
  404.             this.hmenu.on('itemclick', this.handleHdMenuClick, this);
  405.         }
  406.         if(g.trackMouseOver){
  407.             this.mainBody.on({
  408.                 scope: this,
  409.                 mouseover: this.onRowOver,
  410.                 mouseout: this.onRowOut
  411.             });
  412.             this.lockedBody.on({
  413.                 scope: this,
  414.                 mouseover: this.onRowOver,
  415.                 mouseout: this.onRowOut
  416.             });
  417.         }
  418.         
  419.         if(g.enableDragDrop || g.enableDrag){
  420.             this.dragZone = new Ext.grid.GridDragZone(g, {
  421.                 ddGroup : g.ddGroup || 'GridDD'
  422.             });
  423.         }
  424.         this.updateHeaderSortState();
  425.     },
  426.     
  427.     layout : function(){
  428.         if(!this.mainBody){
  429.             return;
  430.         }
  431.         var g = this.grid;
  432.         var c = g.getGridEl();
  433.         var csize = c.getSize(true);
  434.         var vw = csize.width;
  435.         if(!g.hideHeaders && (vw < 20 || csize.height < 20)){
  436.             return;
  437.         }
  438.         this.syncHeaderHeight();
  439.         if(g.autoHeight){
  440.             this.scroller.dom.style.overflow = 'visible';
  441.             this.lockedScroller.dom.style.overflow = 'visible';
  442.             if(Ext.isWebKit){
  443.                 this.scroller.dom.style.position = 'static';
  444.                 this.lockedScroller.dom.style.position = 'static';
  445.             }
  446.         }else{
  447.             this.el.setSize(csize.width, csize.height);
  448.             var hdHeight = this.mainHd.getHeight();
  449.             var vh = csize.height - (hdHeight);
  450.         }
  451.         this.updateLockedWidth();
  452.         if(this.forceFit){
  453.             if(this.lastViewWidth != vw){
  454.                 this.fitColumns(false, false);
  455.                 this.lastViewWidth = vw;
  456.             }
  457.         }else {
  458.             this.autoExpand();
  459.             this.syncHeaderScroll();
  460.         }
  461.         this.onLayout(vw, vh);
  462.     },
  463.     
  464.     getOffsetWidth : function() {
  465.         return (this.cm.getTotalWidth() - this.cm.getTotalLockedWidth() + this.getScrollOffset()) + 'px';
  466.     },
  467.     
  468.     renderHeaders : function(){
  469.         var cm = this.cm,
  470.             ts = this.templates,
  471.             ct = ts.hcell,
  472.             cb = [], lcb = [],
  473.             p = {},
  474.             len = cm.getColumnCount(),
  475.             last = len - 1;
  476.         for(var i = 0; i < len; i++){
  477.             p.id = cm.getColumnId(i);
  478.             p.value = cm.getColumnHeader(i) || '';
  479.             p.style = this.getColumnStyle(i, true);
  480.             p.tooltip = this.getColumnTooltip(i);
  481.             p.css = (i === 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '')) +
  482.                 (cm.config[i].headerCls ? ' ' + cm.config[i].headerCls : '');
  483.             if(cm.config[i].align == 'right'){
  484.                 p.istyle = 'padding-right:16px';
  485.             } else {
  486.                 delete p.istyle;
  487.             }
  488.             if(cm.isLocked(i)){
  489.                 lcb[lcb.length] = ct.apply(p);
  490.             }else{
  491.                 cb[cb.length] = ct.apply(p);
  492.             }
  493.         }
  494.         return [ts.header.apply({cells: cb.join(''), tstyle:'width:'+this.getTotalWidth()+';'}),
  495.                 ts.header.apply({cells: lcb.join(''), tstyle:'width:'+this.getLockedWidth()+';'})];
  496.     },
  497.     
  498.     updateHeaders : function(){
  499.         var hd = this.renderHeaders();
  500.         this.innerHd.firstChild.innerHTML = hd[0];
  501.         this.innerHd.firstChild.style.width = this.getOffsetWidth();
  502.         this.innerHd.firstChild.firstChild.style.width = this.getTotalWidth();
  503.         this.lockedInnerHd.firstChild.innerHTML = hd[1];
  504.         var lw = this.getLockedWidth();
  505.         this.lockedInnerHd.firstChild.style.width = lw;
  506.         this.lockedInnerHd.firstChild.firstChild.style.width = lw;
  507.     },
  508.     
  509.     getResolvedXY : function(resolved){
  510.         if(!resolved){
  511.             return null;
  512.         }
  513.         var c = resolved.cell, r = resolved.row;
  514.         return c ? Ext.fly(c).getXY() : [this.scroller.getX(), Ext.fly(r).getY()];
  515.     },
  516.     
  517.     syncFocusEl : function(row, col, hscroll){
  518.         Ext.ux.grid.LockingGridView.superclass.syncFocusEl.call(this, row, col, col < this.cm.getLockedCount() ? false : hscroll);
  519.     },
  520.     
  521.     ensureVisible : function(row, col, hscroll){
  522.         return Ext.ux.grid.LockingGridView.superclass.ensureVisible.call(this, row, col, col < this.cm.getLockedCount() ? false : hscroll);
  523.     },
  524.     
  525.     insertRows : function(dm, firstRow, lastRow, isUpdate){
  526.         var last = dm.getCount() - 1;
  527.         if(!isUpdate && firstRow === 0 && lastRow >= last){
  528.             this.refresh();
  529.         }else{
  530.             if(!isUpdate){
  531.                 this.fireEvent('beforerowsinserted', this, firstRow, lastRow);
  532.             }
  533.             var html = this.renderRows(firstRow, lastRow),
  534.                 before = this.getRow(firstRow);
  535.             if(before){
  536.                 if(firstRow === 0){
  537.                     this.removeRowClass(0, this.firstRowCls);
  538.                 }
  539.                 Ext.DomHelper.insertHtml('beforeBegin', before, html[0]);
  540.                 before = this.getLockedRow(firstRow);
  541.                 Ext.DomHelper.insertHtml('beforeBegin', before, html[1]);
  542.             }else{
  543.                 this.removeRowClass(last - 1, this.lastRowCls);
  544.                 Ext.DomHelper.insertHtml('beforeEnd', this.mainBody.dom, html[0]);
  545.                 Ext.DomHelper.insertHtml('beforeEnd', this.lockedBody.dom, html[1]);
  546.             }
  547.             if(!isUpdate){
  548.                 this.fireEvent('rowsinserted', this, firstRow, lastRow);
  549.                 this.processRows(firstRow);
  550.             }else if(firstRow === 0 || firstRow >= last){
  551.                 this.addRowClass(firstRow, firstRow === 0 ? this.firstRowCls : this.lastRowCls);
  552.             }
  553.         }
  554.         this.syncFocusEl(firstRow);
  555.     },
  556.     
  557.     getColumnStyle : function(col, isHeader){
  558.         var style = !isHeader ? this.cm.config[col].cellStyle || this.cm.config[col].css || '' : this.cm.config[col].headerStyle || '';
  559.         style += 'width:'+this.getColumnWidth(col)+';';
  560.         if(this.cm.isHidden(col)){
  561.             style += 'display:none;';
  562.         }
  563.         var align = this.cm.config[col].align;
  564.         if(align){
  565.             style += 'text-align:'+align+';';
  566.         }
  567.         return style;
  568.     },
  569.     
  570.     getLockedWidth : function() {
  571.         return this.cm.getTotalLockedWidth() + 'px';
  572.     },
  573.     
  574.     getTotalWidth : function() {
  575.         return (this.cm.getTotalWidth() - this.cm.getTotalLockedWidth()) + 'px';
  576.     },
  577.     
  578.     getColumnData : function(){
  579.         var cs = [], cm = this.cm, colCount = cm.getColumnCount();
  580.         for(var i = 0; i < colCount; i++){
  581.             var name = cm.getDataIndex(i);
  582.             cs[i] = {
  583.                 name : (!Ext.isDefined(name) ? this.ds.fields.get(i).name : name),
  584.                 renderer : cm.getRenderer(i),
  585.                 id : cm.getColumnId(i),
  586.                 style : this.getColumnStyle(i),
  587.                 locked : cm.isLocked(i)
  588.             };
  589.         }
  590.         return cs;
  591.     },
  592.     
  593.     renderBody : function(){
  594.         var markup = this.renderRows() || ['&#160;', '&#160;'];
  595.         return [this.templates.body.apply({rows: markup[0]}), this.templates.body.apply({rows: markup[1]})];
  596.     },
  597.     
  598.     refreshRow : function(record){
  599.         Ext.ux.grid.LockingGridView.superclass.refreshRow.call(this, record);
  600.         var index = Ext.isNumber(record) ? record : this.ds.indexOf(record);
  601.         this.getLockedRow(index).rowIndex = index;
  602.     },
  603.     
  604.     refresh : function(headersToo){
  605.         this.fireEvent('beforerefresh', this);
  606.         this.grid.stopEditing(true);
  607.         var result = this.renderBody();
  608.         this.mainBody.update(result[0]).setWidth(this.getTotalWidth());
  609.         this.lockedBody.update(result[1]).setWidth(this.getLockedWidth());
  610.         if(headersToo === true){
  611.             this.updateHeaders();
  612.             this.updateHeaderSortState();
  613.         }
  614.         this.processRows(0, true);
  615.         this.layout();
  616.         this.applyEmptyText();
  617.         this.fireEvent('refresh', this);
  618.     },
  619.     
  620.     onDenyColumnLock : function(){
  621.     },
  622.     
  623.     initData : function(ds, cm){
  624.         if(this.cm){
  625.             this.cm.un('columnlockchange', this.onColumnLock, this);
  626.         }
  627.         Ext.ux.grid.LockingGridView.superclass.initData.call(this, ds, cm);
  628.         if(this.cm){
  629.             this.cm.on('columnlockchange', this.onColumnLock, this);
  630.         }
  631.     },
  632.     
  633.     onColumnLock : function(){
  634.         this.refresh(true);
  635.     },
  636.     
  637.     handleHdMenuClick : function(item){
  638.         var index = this.hdCtxIndex,
  639.             cm = this.cm,
  640.             id = item.getItemId(),
  641.             llen = cm.getLockedCount();
  642.         switch(id){
  643.             case 'lock':
  644.                 if(cm.getColumnCount(true) <= llen + 1){
  645.                     this.onDenyColumnLock();
  646.                     return;
  647.                 }
  648.                 if(llen != index){
  649.                     cm.setLocked(index, true, true);
  650.                     cm.moveColumn(index, llen);
  651.                     this.grid.fireEvent('columnmove', index, llen);
  652.                 }else{
  653.                     cm.setLocked(index, true);
  654.                 }
  655.             break;
  656.             case 'unlock':
  657.                 if(llen - 1 != index){
  658.                     cm.setLocked(index, false, true);
  659.                     cm.moveColumn(index, llen - 1);
  660.                     this.grid.fireEvent('columnmove', index, llen - 1);
  661.                 }else{
  662.                     cm.setLocked(index, false);
  663.                 }
  664.             break;
  665.             default:
  666.                 return Ext.ux.grid.LockingGridView.superclass.handleHdMenuClick.call(this, item);
  667.         }
  668.         return true;
  669.     },
  670.     
  671.     handleHdDown : function(e, t){
  672.         Ext.ux.grid.LockingGridView.superclass.handleHdDown.call(this, e, t);
  673.         if(this.grid.enableColLock !== false){
  674.             if(Ext.fly(t).hasClass('x-grid3-hd-btn')){
  675.                 var hd = this.findHeaderCell(t),
  676.                     index = this.getCellIndex(hd),
  677.                     ms = this.hmenu.items, cm = this.cm;
  678.                 ms.get('lock').setDisabled(cm.isLocked(index));
  679.                 ms.get('unlock').setDisabled(!cm.isLocked(index));
  680.             }
  681.         }
  682.     },
  683.     
  684.     syncHeaderHeight: function(){
  685.         this.innerHd.firstChild.firstChild.style.height = 'auto';
  686.         this.lockedInnerHd.firstChild.firstChild.style.height = 'auto';
  687.         var hd = this.innerHd.firstChild.firstChild.offsetHeight,
  688.             lhd = this.lockedInnerHd.firstChild.firstChild.offsetHeight,
  689.             height = (lhd > hd ? lhd : hd) + 'px';
  690.         this.innerHd.firstChild.firstChild.style.height = height;
  691.         this.lockedInnerHd.firstChild.firstChild.style.height = height;
  692.     },
  693.     
  694.     updateLockedWidth: function(){
  695.         var lw = this.cm.getTotalLockedWidth(),
  696.             tw = this.cm.getTotalWidth() - lw,
  697.             csize = this.grid.getGridEl().getSize(true),
  698.             lp = Ext.isBorderBox ? 0 : this.lockedBorderWidth,
  699.             rp = Ext.isBorderBox ? 0 : this.rowBorderWidth,
  700.             vw = (csize.width - lw - lp - rp) + 'px',
  701.             so = this.getScrollOffset();
  702.         if(!this.grid.autoHeight){
  703.             var vh = (csize.height - this.mainHd.getHeight()) + 'px';
  704.             this.lockedScroller.dom.style.height = vh;
  705.             this.scroller.dom.style.height = vh;
  706.         }
  707.         this.lockedWrap.dom.style.width = (lw + rp) + 'px';
  708.         this.scroller.dom.style.width = vw;
  709.         this.mainWrap.dom.style.left = (lw + lp + rp) + 'px';
  710.         if(this.innerHd){
  711.             this.lockedInnerHd.firstChild.style.width = lw + 'px';
  712.             this.lockedInnerHd.firstChild.firstChild.style.width = lw + 'px';
  713.             this.innerHd.style.width = vw;
  714.             this.innerHd.firstChild.style.width = (tw + rp + so) + 'px';
  715.             this.innerHd.firstChild.firstChild.style.width = tw + 'px';
  716.         }
  717.         if(this.mainBody){
  718.             this.lockedBody.dom.style.width = (lw + rp) + 'px';
  719.             this.mainBody.dom.style.width = (tw + rp) + 'px';
  720.         }
  721.     }
  722. });
  723. Ext.ux.grid.LockingColumnModel = Ext.extend(Ext.grid.ColumnModel, {
  724.     isLocked : function(colIndex){
  725.         return this.config[colIndex].locked === true;
  726.     },
  727.     
  728.     setLocked : function(colIndex, value, suppressEvent){
  729.         if(this.isLocked(colIndex) == value){
  730.             return;
  731.         }
  732.         this.config[colIndex].locked = value;
  733.         if(!suppressEvent){
  734.             this.fireEvent('columnlockchange', this, colIndex, value);
  735.         }
  736.     },
  737.     
  738.     getTotalLockedWidth : function(){
  739.         var totalWidth = 0;
  740.         for(var i = 0, len = this.config.length; i < len; i++){
  741.             if(this.isLocked(i) && !this.isHidden(i)){
  742.                 totalWidth += this.getColumnWidth(i);
  743.             }
  744.         }
  745.         return totalWidth;
  746.     },
  747.     
  748.     getLockedCount : function(){
  749.         for(var i = 0, len = this.config.length; i < len; i++){
  750.             if(!this.isLocked(i)){
  751.                 return i;
  752.             }
  753.         }
  754.     },
  755.     
  756.     moveColumn : function(oldIndex, newIndex){
  757.         if(oldIndex < newIndex && this.isLocked(oldIndex) && !this.isLocked(newIndex)){
  758.             this.setLocked(oldIndex, false, true);
  759.         }else if(oldIndex > newIndex && !this.isLocked(oldIndex) && this.isLocked(newIndex)){
  760.             this.setLocked(oldIndex, true, true);
  761.         }
  762.         Ext.ux.grid.LockingColumnModel.superclass.moveColumn.apply(this, arguments);
  763.     }
  764. });