X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/2e847cf21b8ab9d15fa167b315ca5b2fa92638fc..6a7e4474cba9d8be4b2ec445e10f1691f7277c50:/examples/ux/LockingGridView.js diff --git a/examples/ux/LockingGridView.js b/examples/ux/LockingGridView.js index 00155617..39673dca 100644 --- a/examples/ux/LockingGridView.js +++ b/examples/ux/LockingGridView.js @@ -1,773 +1,820 @@ /*! - * Ext JS Library 3.1.1 - * Copyright(c) 2006-2010 Ext JS, LLC + * Ext JS Library 3.2.0 + * Copyright(c) 2006-2010 Ext JS, Inc. * licensing@extjs.com * http://www.extjs.com/license */ -Ext.ns('Ext.ux.grid'); - -Ext.ux.grid.LockingGridView = Ext.extend(Ext.grid.GridView, { - lockText : 'Lock', - unlockText : 'Unlock', - rowBorderWidth : 1, - lockedBorderWidth : 1, - /* - * This option ensures that height between the rows is synchronized - * between the locked and unlocked sides. This option only needs to be used - * when the row heights isn't predictable. - */ - syncHeights: false, - initTemplates : function(){ - var ts = this.templates || {}; - if(!ts.master){ - ts.master = new Ext.Template( - '
', - '
', - '
{lockedHeader}
', - '
{lockedBody}
', - '
', - '
', - '
{header}
', - '
{body}
', - '
', - '
 
', - '
 
', - '
' - ); - } - this.templates = ts; - Ext.ux.grid.LockingGridView.superclass.initTemplates.call(this); - }, - getEditorParent : function(ed){ - return this.el.dom; - }, - initElements : function(){ - var E = Ext.Element; - var el = this.grid.getGridEl().dom.firstChild; - var cs = el.childNodes; - this.el = new E(el); - this.lockedWrap = new E(cs[0]); - this.lockedHd = new E(this.lockedWrap.dom.firstChild); - this.lockedInnerHd = this.lockedHd.dom.firstChild; - this.lockedScroller = new E(this.lockedWrap.dom.childNodes[1]); - this.lockedBody = new E(this.lockedScroller.dom.firstChild); - this.mainWrap = new E(cs[1]); - this.mainHd = new E(this.mainWrap.dom.firstChild); - if(this.grid.hideHeaders){ - this.lockedHd.setDisplayed(false); - this.mainHd.setDisplayed(false); - } - this.innerHd = this.mainHd.dom.firstChild; - this.scroller = new E(this.mainWrap.dom.childNodes[1]); - if(this.forceFit){ - this.scroller.setStyle('overflow-x', 'hidden'); - } - this.mainBody = new E(this.scroller.dom.firstChild); - this.focusEl = new E(this.scroller.dom.childNodes[1]); - this.focusEl.swallowEvent('click', true); - this.resizeMarker = new E(cs[2]); - this.resizeProxy = new E(cs[3]); - }, - - getLockedRows : function(){ - return this.hasRows() ? this.lockedBody.dom.childNodes : []; - }, - - getLockedRow : function(row){ - return this.getLockedRows()[row]; - }, - - getCell : function(row, col){ - var llen = this.cm.getLockedCount(); - if(col < llen){ - return this.getLockedRow(row).getElementsByTagName('td')[col]; - } - return Ext.ux.grid.LockingGridView.superclass.getCell.call(this, row, col - llen); - }, - - getHeaderCell : function(index){ - var llen = this.cm.getLockedCount(); - if(index < llen){ - return this.lockedHd.dom.getElementsByTagName('td')[index]; - } - return Ext.ux.grid.LockingGridView.superclass.getHeaderCell.call(this, index - llen); - }, - - addRowClass : function(row, cls){ - var r = this.getLockedRow(row); - if(r){ - this.fly(r).addClass(cls); - } - Ext.ux.grid.LockingGridView.superclass.addRowClass.call(this, row, cls); - }, - - removeRowClass : function(row, cls){ - var r = this.getLockedRow(row); - if(r){ - this.fly(r).removeClass(cls); - } - Ext.ux.grid.LockingGridView.superclass.removeRowClass.call(this, row, cls); - }, - - removeRow : function(row) { - Ext.removeNode(this.getLockedRow(row)); - Ext.ux.grid.LockingGridView.superclass.removeRow.call(this, row); - }, - - removeRows : function(firstRow, lastRow){ - var bd = this.lockedBody.dom; - for(var rowIndex = firstRow; rowIndex <= lastRow; rowIndex++){ - Ext.removeNode(bd.childNodes[firstRow]); - } - Ext.ux.grid.LockingGridView.superclass.removeRows.call(this, firstRow, lastRow); - }, - - syncScroll : function(e){ - var mb = this.scroller.dom; - this.lockedScroller.dom.scrollTop = mb.scrollTop; - Ext.ux.grid.LockingGridView.superclass.syncScroll.call(this, e); - }, - - updateSortIcon : function(col, dir){ - var sc = this.sortClasses, - lhds = this.lockedHd.select('td').removeClass(sc), - hds = this.mainHd.select('td').removeClass(sc), - llen = this.cm.getLockedCount(), - cls = sc[dir == 'DESC' ? 1 : 0]; - if(col < llen){ - lhds.item(col).addClass(cls); - }else{ - hds.item(col - llen).addClass(cls); - } - }, - - updateAllColumnWidths : function(){ - var tw = this.getTotalWidth(), - clen = this.cm.getColumnCount(), - lw = this.getLockedWidth(), - llen = this.cm.getLockedCount(), - ws = [], len, i; - this.updateLockedWidth(); - for(i = 0; i < clen; i++){ - ws[i] = this.getColumnWidth(i); - var hd = this.getHeaderCell(i); - hd.style.width = ws[i]; - } - var lns = this.getLockedRows(), ns = this.getRows(), row, trow, j; - for(i = 0, len = ns.length; i < len; i++){ - row = lns[i]; - row.style.width = lw; - if(row.firstChild){ - row.firstChild.style.width = lw; - trow = row.firstChild.rows[0]; - for (j = 0; j < llen; j++) { - trow.childNodes[j].style.width = ws[j]; - } - } - row = ns[i]; - row.style.width = tw; - if(row.firstChild){ - row.firstChild.style.width = tw; - trow = row.firstChild.rows[0]; - for (j = llen; j < clen; j++) { - trow.childNodes[j - llen].style.width = ws[j]; - } - } - } - this.onAllColumnWidthsUpdated(ws, tw); - this.syncHeaderHeight(); - }, - - updateColumnWidth : function(col, width){ - var w = this.getColumnWidth(col), - llen = this.cm.getLockedCount(), - ns, rw, c, row; - this.updateLockedWidth(); - if(col < llen){ - ns = this.getLockedRows(); - rw = this.getLockedWidth(); - c = col; - }else{ - ns = this.getRows(); - rw = this.getTotalWidth(); - c = col - llen; - } - var hd = this.getHeaderCell(col); - hd.style.width = w; - for(var i = 0, len = ns.length; i < len; i++){ - row = ns[i]; - row.style.width = rw; - if(row.firstChild){ - row.firstChild.style.width = rw; - row.firstChild.rows[0].childNodes[c].style.width = w; - } - } - this.onColumnWidthUpdated(col, w, this.getTotalWidth()); - this.syncHeaderHeight(); - }, - - updateColumnHidden : function(col, hidden){ - var llen = this.cm.getLockedCount(), - ns, rw, c, row, - display = hidden ? 'none' : ''; - this.updateLockedWidth(); - if(col < llen){ - ns = this.getLockedRows(); - rw = this.getLockedWidth(); - c = col; - }else{ - ns = this.getRows(); - rw = this.getTotalWidth(); - c = col - llen; - } - var hd = this.getHeaderCell(col); - hd.style.display = display; - for(var i = 0, len = ns.length; i < len; i++){ - row = ns[i]; - row.style.width = rw; - if(row.firstChild){ - row.firstChild.style.width = rw; - row.firstChild.rows[0].childNodes[c].style.display = display; - } - } - this.onColumnHiddenUpdated(col, hidden, this.getTotalWidth()); - delete this.lastViewWidth; - this.layout(); - }, - - doRender : function(cs, rs, ds, startRow, colCount, stripe){ - var ts = this.templates, ct = ts.cell, rt = ts.row, last = colCount-1, - tstyle = 'width:'+this.getTotalWidth()+';', - lstyle = 'width:'+this.getLockedWidth()+';', - buf = [], lbuf = [], cb, lcb, c, p = {}, rp = {}, r; - for(var j = 0, len = rs.length; j < len; j++){ - r = rs[j]; cb = []; lcb = []; - var rowIndex = (j+startRow); - for(var i = 0; i < colCount; i++){ - c = cs[i]; - p.id = c.id; - p.css = (i === 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '')) + - (this.cm.config[i].cellCls ? ' ' + this.cm.config[i].cellCls : ''); - p.attr = p.cellAttr = ''; - p.value = c.renderer(r.data[c.name], p, r, rowIndex, i, ds); - p.style = c.style; - if(Ext.isEmpty(p.value)){ - p.value = ' '; - } - if(this.markDirty && r.dirty && Ext.isDefined(r.modified[c.name])){ - p.css += ' x-grid3-dirty-cell'; - } - if(c.locked){ - lcb[lcb.length] = ct.apply(p); - }else{ - cb[cb.length] = ct.apply(p); - } - } - var alt = []; - if(stripe && ((rowIndex+1) % 2 === 0)){ - alt[0] = 'x-grid3-row-alt'; - } - if(r.dirty){ - alt[1] = ' x-grid3-dirty-row'; - } - rp.cols = colCount; - if(this.getRowClass){ - alt[2] = this.getRowClass(r, rowIndex, rp, ds); - } - rp.alt = alt.join(' '); - rp.cells = cb.join(''); - rp.tstyle = tstyle; - buf[buf.length] = rt.apply(rp); - rp.cells = lcb.join(''); - rp.tstyle = lstyle; - lbuf[lbuf.length] = rt.apply(rp); - } - return [buf.join(''), lbuf.join('')]; - }, - processRows : function(startRow, skipStripe){ - if(!this.ds || this.ds.getCount() < 1){ - return; - } - var rows = this.getRows(), - lrows = this.getLockedRows(), - row, lrow; - skipStripe = skipStripe || !this.grid.stripeRows; - startRow = startRow || 0; - for(var i = 0, len = rows.length; i < len; ++i){ - row = rows[i]; - lrow = lrows[i]; - row.rowIndex = i; - lrow.rowIndex = i; - if(!skipStripe){ - row.className = row.className.replace(this.rowClsRe, ' '); - lrow.className = lrow.className.replace(this.rowClsRe, ' '); - if ((i + 1) % 2 === 0){ - row.className += ' x-grid3-row-alt'; - lrow.className += ' x-grid3-row-alt'; - } - } - if(this.syncHeights){ - var el1 = Ext.get(row), - el2 = Ext.get(lrow), - h1 = el1.getHeight(), - h2 = el2.getHeight(); - - if(h1 > h2){ - el2.setHeight(h1); - }else if(h2 > h1){ - el1.setHeight(h2); - } - } - } - if(startRow === 0){ - Ext.fly(rows[0]).addClass(this.firstRowCls); - Ext.fly(lrows[0]).addClass(this.firstRowCls); - } - Ext.fly(rows[rows.length - 1]).addClass(this.lastRowCls); - Ext.fly(lrows[lrows.length - 1]).addClass(this.lastRowCls); - }, - - afterRender : function(){ - if(!this.ds || !this.cm){ - return; - } - var bd = this.renderRows() || [' ', ' ']; - this.mainBody.dom.innerHTML = bd[0]; - this.lockedBody.dom.innerHTML = bd[1]; - this.processRows(0, true); - if(this.deferEmptyText !== true){ - this.applyEmptyText(); - } - }, - - renderUI : function(){ - var header = this.renderHeaders(); - var body = this.templates.body.apply({rows:' '}); - var html = this.templates.master.apply({ - body: body, - header: header[0], - ostyle: 'width:'+this.getOffsetWidth()+';', - bstyle: 'width:'+this.getTotalWidth()+';', - lockedBody: body, - lockedHeader: header[1], - lstyle: 'width:'+this.getLockedWidth()+';' - }); - var g = this.grid; - g.getGridEl().dom.innerHTML = html; - this.initElements(); - Ext.fly(this.innerHd).on('click', this.handleHdDown, this); - Ext.fly(this.lockedInnerHd).on('click', this.handleHdDown, this); - this.mainHd.on({ - scope: this, - mouseover: this.handleHdOver, - mouseout: this.handleHdOut, - mousemove: this.handleHdMove - }); - this.lockedHd.on({ - scope: this, - mouseover: this.handleHdOver, - mouseout: this.handleHdOut, - mousemove: this.handleHdMove - }); - this.scroller.on('scroll', this.syncScroll, this); - if(g.enableColumnResize !== false){ - this.splitZone = new Ext.grid.GridView.SplitDragZone(g, this.mainHd.dom); - this.splitZone.setOuterHandleElId(Ext.id(this.lockedHd.dom)); - this.splitZone.setOuterHandleElId(Ext.id(this.mainHd.dom)); - } - if(g.enableColumnMove){ - this.columnDrag = new Ext.grid.GridView.ColumnDragZone(g, this.innerHd); - this.columnDrag.setOuterHandleElId(Ext.id(this.lockedInnerHd)); - this.columnDrag.setOuterHandleElId(Ext.id(this.innerHd)); - this.columnDrop = new Ext.grid.HeaderDropZone(g, this.mainHd.dom); - } - if(g.enableHdMenu !== false){ - this.hmenu = new Ext.menu.Menu({id: g.id + '-hctx'}); - this.hmenu.add( - {itemId: 'asc', text: this.sortAscText, cls: 'xg-hmenu-sort-asc'}, - {itemId: 'desc', text: this.sortDescText, cls: 'xg-hmenu-sort-desc'} - ); - if(this.grid.enableColLock !== false){ - this.hmenu.add('-', - {itemId: 'lock', text: this.lockText, cls: 'xg-hmenu-lock'}, - {itemId: 'unlock', text: this.unlockText, cls: 'xg-hmenu-unlock'} - ); - } - if(g.enableColumnHide !== false){ - this.colMenu = new Ext.menu.Menu({id:g.id + '-hcols-menu'}); - this.colMenu.on({ - scope: this, - beforeshow: this.beforeColMenuShow, - itemclick: this.handleHdMenuClick - }); - this.hmenu.add('-', { - itemId:'columns', - hideOnClick: false, - text: this.columnsText, - menu: this.colMenu, - iconCls: 'x-cols-icon' - }); - } - this.hmenu.on('itemclick', this.handleHdMenuClick, this); - } - if(g.trackMouseOver){ - this.mainBody.on({ - scope: this, - mouseover: this.onRowOver, - mouseout: this.onRowOut - }); - this.lockedBody.on({ - scope: this, - mouseover: this.onRowOver, - mouseout: this.onRowOut - }); - } - - if(g.enableDragDrop || g.enableDrag){ - this.dragZone = new Ext.grid.GridDragZone(g, { - ddGroup : g.ddGroup || 'GridDD' - }); - } - this.updateHeaderSortState(); - }, - - layout : function(){ - if(!this.mainBody){ - return; - } - var g = this.grid; - var c = g.getGridEl(); - var csize = c.getSize(true); - var vw = csize.width; - if(!g.hideHeaders && (vw < 20 || csize.height < 20)){ - return; - } - this.syncHeaderHeight(); - if(g.autoHeight){ - this.scroller.dom.style.overflow = 'visible'; - this.lockedScroller.dom.style.overflow = 'visible'; - if(Ext.isWebKit){ - this.scroller.dom.style.position = 'static'; - this.lockedScroller.dom.style.position = 'static'; - } - }else{ - this.el.setSize(csize.width, csize.height); - var hdHeight = this.mainHd.getHeight(); - var vh = csize.height - (hdHeight); - } - this.updateLockedWidth(); - if(this.forceFit){ - if(this.lastViewWidth != vw){ - this.fitColumns(false, false); - this.lastViewWidth = vw; - } - }else { - this.autoExpand(); - this.syncHeaderScroll(); - } - this.onLayout(vw, vh); - }, - - getOffsetWidth : function() { - return (this.cm.getTotalWidth() - this.cm.getTotalLockedWidth() + this.getScrollOffset()) + 'px'; - }, - - renderHeaders : function(){ - var cm = this.cm, - ts = this.templates, - ct = ts.hcell, - cb = [], lcb = [], - p = {}, - len = cm.getColumnCount(), - last = len - 1; - for(var i = 0; i < len; i++){ - p.id = cm.getColumnId(i); - p.value = cm.getColumnHeader(i) || ''; - p.style = this.getColumnStyle(i, true); - p.tooltip = this.getColumnTooltip(i); - p.css = (i === 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '')) + - (cm.config[i].headerCls ? ' ' + cm.config[i].headerCls : ''); - if(cm.config[i].align == 'right'){ - p.istyle = 'padding-right:16px'; - } else { - delete p.istyle; - } - if(cm.isLocked(i)){ - lcb[lcb.length] = ct.apply(p); - }else{ - cb[cb.length] = ct.apply(p); - } - } - return [ts.header.apply({cells: cb.join(''), tstyle:'width:'+this.getTotalWidth()+';'}), - ts.header.apply({cells: lcb.join(''), tstyle:'width:'+this.getLockedWidth()+';'})]; - }, - - updateHeaders : function(){ - var hd = this.renderHeaders(); - this.innerHd.firstChild.innerHTML = hd[0]; - this.innerHd.firstChild.style.width = this.getOffsetWidth(); - this.innerHd.firstChild.firstChild.style.width = this.getTotalWidth(); - this.lockedInnerHd.firstChild.innerHTML = hd[1]; - var lw = this.getLockedWidth(); - this.lockedInnerHd.firstChild.style.width = lw; - this.lockedInnerHd.firstChild.firstChild.style.width = lw; - }, - - getResolvedXY : function(resolved){ - if(!resolved){ - return null; - } - var c = resolved.cell, r = resolved.row; - return c ? Ext.fly(c).getXY() : [this.scroller.getX(), Ext.fly(r).getY()]; - }, - - syncFocusEl : function(row, col, hscroll){ - Ext.ux.grid.LockingGridView.superclass.syncFocusEl.call(this, row, col, col < this.cm.getLockedCount() ? false : hscroll); - }, - - ensureVisible : function(row, col, hscroll){ - return Ext.ux.grid.LockingGridView.superclass.ensureVisible.call(this, row, col, col < this.cm.getLockedCount() ? false : hscroll); - }, - - insertRows : function(dm, firstRow, lastRow, isUpdate){ - var last = dm.getCount() - 1; - if(!isUpdate && firstRow === 0 && lastRow >= last){ - this.refresh(); - }else{ - if(!isUpdate){ - this.fireEvent('beforerowsinserted', this, firstRow, lastRow); - } - var html = this.renderRows(firstRow, lastRow), - before = this.getRow(firstRow); - if(before){ - if(firstRow === 0){ - this.removeRowClass(0, this.firstRowCls); - } - Ext.DomHelper.insertHtml('beforeBegin', before, html[0]); - before = this.getLockedRow(firstRow); - Ext.DomHelper.insertHtml('beforeBegin', before, html[1]); - }else{ - this.removeRowClass(last - 1, this.lastRowCls); - Ext.DomHelper.insertHtml('beforeEnd', this.mainBody.dom, html[0]); - Ext.DomHelper.insertHtml('beforeEnd', this.lockedBody.dom, html[1]); - } - if(!isUpdate){ - this.fireEvent('rowsinserted', this, firstRow, lastRow); - this.processRows(firstRow); - }else if(firstRow === 0 || firstRow >= last){ - this.addRowClass(firstRow, firstRow === 0 ? this.firstRowCls : this.lastRowCls); - } - } - this.syncFocusEl(firstRow); - }, - - getColumnStyle : function(col, isHeader){ - var style = !isHeader ? this.cm.config[col].cellStyle || this.cm.config[col].css || '' : this.cm.config[col].headerStyle || ''; - style += 'width:'+this.getColumnWidth(col)+';'; - if(this.cm.isHidden(col)){ - style += 'display:none;'; - } - var align = this.cm.config[col].align; - if(align){ - style += 'text-align:'+align+';'; - } - return style; - }, - - getLockedWidth : function() { - return this.cm.getTotalLockedWidth() + 'px'; - }, - - getTotalWidth : function() { - return (this.cm.getTotalWidth() - this.cm.getTotalLockedWidth()) + 'px'; - }, - - getColumnData : function(){ - var cs = [], cm = this.cm, colCount = cm.getColumnCount(); - for(var i = 0; i < colCount; i++){ - var name = cm.getDataIndex(i); - cs[i] = { - name : (!Ext.isDefined(name) ? this.ds.fields.get(i).name : name), - renderer : cm.getRenderer(i), - id : cm.getColumnId(i), - style : this.getColumnStyle(i), - locked : cm.isLocked(i) - }; - } - return cs; - }, - - renderBody : function(){ - var markup = this.renderRows() || [' ', ' ']; - return [this.templates.body.apply({rows: markup[0]}), this.templates.body.apply({rows: markup[1]})]; - }, - - refreshRow : function(record){ - Ext.ux.grid.LockingGridView.superclass.refreshRow.call(this, record); - var index = Ext.isNumber(record) ? record : this.ds.indexOf(record); - this.getLockedRow(index).rowIndex = index; - }, - - refresh : function(headersToo){ - this.fireEvent('beforerefresh', this); - this.grid.stopEditing(true); - var result = this.renderBody(); - this.mainBody.update(result[0]).setWidth(this.getTotalWidth()); - this.lockedBody.update(result[1]).setWidth(this.getLockedWidth()); - if(headersToo === true){ - this.updateHeaders(); - this.updateHeaderSortState(); - } - this.processRows(0, true); - this.layout(); - this.applyEmptyText(); - this.fireEvent('refresh', this); - }, - - onDenyColumnLock : function(){ - - }, - - initData : function(ds, cm){ - if(this.cm){ - this.cm.un('columnlockchange', this.onColumnLock, this); - } - Ext.ux.grid.LockingGridView.superclass.initData.call(this, ds, cm); - if(this.cm){ - this.cm.on('columnlockchange', this.onColumnLock, this); - } - }, - - onColumnLock : function(){ - this.refresh(true); - }, - - handleHdMenuClick : function(item){ - var index = this.hdCtxIndex, - cm = this.cm, - id = item.getItemId(), - llen = cm.getLockedCount(); - switch(id){ - case 'lock': - if(cm.getColumnCount(true) <= llen + 1){ - this.onDenyColumnLock(); - return; - } - if(llen != index){ - cm.setLocked(index, true, true); - cm.moveColumn(index, llen); - this.grid.fireEvent('columnmove', index, llen); - }else{ - cm.setLocked(index, true); - } - break; - case 'unlock': - if(llen - 1 != index){ - cm.setLocked(index, false, true); - cm.moveColumn(index, llen - 1); - this.grid.fireEvent('columnmove', index, llen - 1); - }else{ - cm.setLocked(index, false); - } - break; - default: - return Ext.ux.grid.LockingGridView.superclass.handleHdMenuClick.call(this, item); - } - return true; - }, - - handleHdDown : function(e, t){ - Ext.ux.grid.LockingGridView.superclass.handleHdDown.call(this, e, t); - if(this.grid.enableColLock !== false){ - if(Ext.fly(t).hasClass('x-grid3-hd-btn')){ - var hd = this.findHeaderCell(t), - index = this.getCellIndex(hd), - ms = this.hmenu.items, cm = this.cm; - ms.get('lock').setDisabled(cm.isLocked(index)); - ms.get('unlock').setDisabled(!cm.isLocked(index)); - } - } - }, - - syncHeaderHeight: function(){ - this.innerHd.firstChild.firstChild.style.height = 'auto'; - this.lockedInnerHd.firstChild.firstChild.style.height = 'auto'; - var hd = this.innerHd.firstChild.firstChild.offsetHeight, - lhd = this.lockedInnerHd.firstChild.firstChild.offsetHeight, - height = (lhd > hd ? lhd : hd) + 'px'; - this.innerHd.firstChild.firstChild.style.height = height; - this.lockedInnerHd.firstChild.firstChild.style.height = height; - }, - - updateLockedWidth: function(){ - var lw = this.cm.getTotalLockedWidth(), - tw = this.cm.getTotalWidth() - lw, - csize = this.grid.getGridEl().getSize(true), - lp = Ext.isBorderBox ? 0 : this.lockedBorderWidth, - rp = Ext.isBorderBox ? 0 : this.rowBorderWidth, - vw = (csize.width - lw - lp - rp) + 'px', - so = this.getScrollOffset(); - if(!this.grid.autoHeight){ - var vh = (csize.height - this.mainHd.getHeight()) + 'px'; - this.lockedScroller.dom.style.height = vh; - this.scroller.dom.style.height = vh; - } - this.lockedWrap.dom.style.width = (lw + rp) + 'px'; - this.scroller.dom.style.width = vw; - this.mainWrap.dom.style.left = (lw + lp + rp) + 'px'; - if(this.innerHd){ - this.lockedInnerHd.firstChild.style.width = lw + 'px'; - this.lockedInnerHd.firstChild.firstChild.style.width = lw + 'px'; - this.innerHd.style.width = vw; - this.innerHd.firstChild.style.width = (tw + rp + so) + 'px'; - this.innerHd.firstChild.firstChild.style.width = tw + 'px'; - } - if(this.mainBody){ - this.lockedBody.dom.style.width = (lw + rp) + 'px'; - this.mainBody.dom.style.width = (tw + rp) + 'px'; - } - } -}); - -Ext.ux.grid.LockingColumnModel = Ext.extend(Ext.grid.ColumnModel, { - isLocked : function(colIndex){ - return this.config[colIndex].locked === true; - }, - - setLocked : function(colIndex, value, suppressEvent){ - if(this.isLocked(colIndex) == value){ - return; - } - this.config[colIndex].locked = value; - if(!suppressEvent){ - this.fireEvent('columnlockchange', this, colIndex, value); - } - }, - - getTotalLockedWidth : function(){ - var totalWidth = 0; - for(var i = 0, len = this.config.length; i < len; i++){ - if(this.isLocked(i) && !this.isHidden(i)){ - totalWidth += this.getColumnWidth(i); - } - } - return totalWidth; - }, - - getLockedCount : function(){ - for(var i = 0, len = this.config.length; i < len; i++){ - if(!this.isLocked(i)){ - return i; - } - } - }, - - moveColumn : function(oldIndex, newIndex){ - if(oldIndex < newIndex && this.isLocked(oldIndex) && !this.isLocked(newIndex)){ - this.setLocked(oldIndex, false, true); - }else if(oldIndex > newIndex && !this.isLocked(oldIndex) && this.isLocked(newIndex)){ - this.setLocked(oldIndex, true, true); - } - Ext.ux.grid.LockingColumnModel.superclass.moveColumn.apply(this, arguments); - } -}); +Ext.ns('Ext.ux.grid'); + +Ext.ux.grid.LockingGridView = Ext.extend(Ext.grid.GridView, { + lockText : 'Lock', + unlockText : 'Unlock', + rowBorderWidth : 1, + lockedBorderWidth : 1, + + /* + * This option ensures that height between the rows is synchronized + * between the locked and unlocked sides. This option only needs to be used + * when the row heights aren't predictable. + */ + syncHeights: false, + + initTemplates : function(){ + var ts = this.templates || {}; + + if (!ts.master) { + ts.master = new Ext.Template( + '
', + '
', + '
{lockedHeader}
', + '
{lockedBody}
', + '
', + '
', + '
{header}
', + '
{body}
', + '
', + '
 
', + '
 
', + '
' + ); + } + + this.templates = ts; + + Ext.ux.grid.LockingGridView.superclass.initTemplates.call(this); + }, + + getEditorParent : function(ed){ + return this.el.dom; + }, + + initElements : function(){ + var E = Ext.Element, + el = this.grid.getGridEl().dom.firstChild, + cs = el.childNodes; + + this.el = new E(el); + this.lockedWrap = new E(cs[0]); + this.lockedHd = new E(this.lockedWrap.dom.firstChild); + this.lockedInnerHd = this.lockedHd.dom.firstChild; + this.lockedScroller = new E(this.lockedWrap.dom.childNodes[1]); + this.lockedBody = new E(this.lockedScroller.dom.firstChild); + this.mainWrap = new E(cs[1]); + this.mainHd = new E(this.mainWrap.dom.firstChild); + + if (this.grid.hideHeaders) { + this.lockedHd.setDisplayed(false); + this.mainHd.setDisplayed(false); + } + + this.innerHd = this.mainHd.dom.firstChild; + this.scroller = new E(this.mainWrap.dom.childNodes[1]); + + if(this.forceFit){ + this.scroller.setStyle('overflow-x', 'hidden'); + } + + this.mainBody = new E(this.scroller.dom.firstChild); + this.focusEl = new E(this.scroller.dom.childNodes[1]); + this.resizeMarker = new E(cs[2]); + this.resizeProxy = new E(cs[3]); + + this.focusEl.swallowEvent('click', true); + }, + + getLockedRows : function(){ + return this.hasRows() ? this.lockedBody.dom.childNodes : []; + }, + + getLockedRow : function(row){ + return this.getLockedRows()[row]; + }, + + getCell : function(row, col){ + var llen = this.cm.getLockedCount(); + if(col < llen){ + return this.getLockedRow(row).getElementsByTagName('td')[col]; + } + return Ext.ux.grid.LockingGridView.superclass.getCell.call(this, row, col - llen); + }, + + getHeaderCell : function(index){ + var llen = this.cm.getLockedCount(); + if(index < llen){ + return this.lockedHd.dom.getElementsByTagName('td')[index]; + } + return Ext.ux.grid.LockingGridView.superclass.getHeaderCell.call(this, index - llen); + }, + + addRowClass : function(row, cls){ + var r = this.getLockedRow(row); + if(r){ + this.fly(r).addClass(cls); + } + Ext.ux.grid.LockingGridView.superclass.addRowClass.call(this, row, cls); + }, + + removeRowClass : function(row, cls){ + var r = this.getLockedRow(row); + if(r){ + this.fly(r).removeClass(cls); + } + Ext.ux.grid.LockingGridView.superclass.removeRowClass.call(this, row, cls); + }, + + removeRow : function(row) { + Ext.removeNode(this.getLockedRow(row)); + Ext.ux.grid.LockingGridView.superclass.removeRow.call(this, row); + }, + + removeRows : function(firstRow, lastRow){ + var bd = this.lockedBody.dom; + for(var rowIndex = firstRow; rowIndex <= lastRow; rowIndex++){ + Ext.removeNode(bd.childNodes[firstRow]); + } + Ext.ux.grid.LockingGridView.superclass.removeRows.call(this, firstRow, lastRow); + }, + + syncScroll : function(e){ + var mb = this.scroller.dom; + this.lockedScroller.dom.scrollTop = mb.scrollTop; + Ext.ux.grid.LockingGridView.superclass.syncScroll.call(this, e); + }, + + updateSortIcon : function(col, dir){ + var sc = this.sortClasses, + lhds = this.lockedHd.select('td').removeClass(sc), + hds = this.mainHd.select('td').removeClass(sc), + llen = this.cm.getLockedCount(), + cls = sc[dir == 'DESC' ? 1 : 0]; + if(col < llen){ + lhds.item(col).addClass(cls); + }else{ + hds.item(col - llen).addClass(cls); + } + }, + + updateAllColumnWidths : function(){ + var tw = this.getTotalWidth(), + clen = this.cm.getColumnCount(), + lw = this.getLockedWidth(), + llen = this.cm.getLockedCount(), + ws = [], len, i; + this.updateLockedWidth(); + for(i = 0; i < clen; i++){ + ws[i] = this.getColumnWidth(i); + var hd = this.getHeaderCell(i); + hd.style.width = ws[i]; + } + var lns = this.getLockedRows(), ns = this.getRows(), row, trow, j; + for(i = 0, len = ns.length; i < len; i++){ + row = lns[i]; + row.style.width = lw; + if(row.firstChild){ + row.firstChild.style.width = lw; + trow = row.firstChild.rows[0]; + for (j = 0; j < llen; j++) { + trow.childNodes[j].style.width = ws[j]; + } + } + row = ns[i]; + row.style.width = tw; + if(row.firstChild){ + row.firstChild.style.width = tw; + trow = row.firstChild.rows[0]; + for (j = llen; j < clen; j++) { + trow.childNodes[j - llen].style.width = ws[j]; + } + } + } + this.onAllColumnWidthsUpdated(ws, tw); + this.syncHeaderHeight(); + }, + + updateColumnWidth : function(col, width){ + var w = this.getColumnWidth(col), + llen = this.cm.getLockedCount(), + ns, rw, c, row; + this.updateLockedWidth(); + if(col < llen){ + ns = this.getLockedRows(); + rw = this.getLockedWidth(); + c = col; + }else{ + ns = this.getRows(); + rw = this.getTotalWidth(); + c = col - llen; + } + var hd = this.getHeaderCell(col); + hd.style.width = w; + for(var i = 0, len = ns.length; i < len; i++){ + row = ns[i]; + row.style.width = rw; + if(row.firstChild){ + row.firstChild.style.width = rw; + row.firstChild.rows[0].childNodes[c].style.width = w; + } + } + this.onColumnWidthUpdated(col, w, this.getTotalWidth()); + this.syncHeaderHeight(); + }, + + updateColumnHidden : function(col, hidden){ + var llen = this.cm.getLockedCount(), + ns, rw, c, row, + display = hidden ? 'none' : ''; + this.updateLockedWidth(); + if(col < llen){ + ns = this.getLockedRows(); + rw = this.getLockedWidth(); + c = col; + }else{ + ns = this.getRows(); + rw = this.getTotalWidth(); + c = col - llen; + } + var hd = this.getHeaderCell(col); + hd.style.display = display; + for(var i = 0, len = ns.length; i < len; i++){ + row = ns[i]; + row.style.width = rw; + if(row.firstChild){ + row.firstChild.style.width = rw; + row.firstChild.rows[0].childNodes[c].style.display = display; + } + } + this.onColumnHiddenUpdated(col, hidden, this.getTotalWidth()); + delete this.lastViewWidth; + this.layout(); + }, + + doRender : function(cs, rs, ds, startRow, colCount, stripe){ + var ts = this.templates, ct = ts.cell, rt = ts.row, last = colCount-1, + tstyle = 'width:'+this.getTotalWidth()+';', + lstyle = 'width:'+this.getLockedWidth()+';', + buf = [], lbuf = [], cb, lcb, c, p = {}, rp = {}, r; + for(var j = 0, len = rs.length; j < len; j++){ + r = rs[j]; cb = []; lcb = []; + var rowIndex = (j+startRow); + for(var i = 0; i < colCount; i++){ + c = cs[i]; + p.id = c.id; + p.css = (i === 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '')) + + (this.cm.config[i].cellCls ? ' ' + this.cm.config[i].cellCls : ''); + p.attr = p.cellAttr = ''; + p.value = c.renderer(r.data[c.name], p, r, rowIndex, i, ds); + p.style = c.style; + if(Ext.isEmpty(p.value)){ + p.value = ' '; + } + if(this.markDirty && r.dirty && Ext.isDefined(r.modified[c.name])){ + p.css += ' x-grid3-dirty-cell'; + } + if(c.locked){ + lcb[lcb.length] = ct.apply(p); + }else{ + cb[cb.length] = ct.apply(p); + } + } + var alt = []; + if(stripe && ((rowIndex+1) % 2 === 0)){ + alt[0] = 'x-grid3-row-alt'; + } + if(r.dirty){ + alt[1] = ' x-grid3-dirty-row'; + } + rp.cols = colCount; + if(this.getRowClass){ + alt[2] = this.getRowClass(r, rowIndex, rp, ds); + } + rp.alt = alt.join(' '); + rp.cells = cb.join(''); + rp.tstyle = tstyle; + buf[buf.length] = rt.apply(rp); + rp.cells = lcb.join(''); + rp.tstyle = lstyle; + lbuf[lbuf.length] = rt.apply(rp); + } + return [buf.join(''), lbuf.join('')]; + }, + processRows : function(startRow, skipStripe){ + if(!this.ds || this.ds.getCount() < 1){ + return; + } + var rows = this.getRows(), + lrows = this.getLockedRows(), + row, lrow; + skipStripe = skipStripe || !this.grid.stripeRows; + startRow = startRow || 0; + for(var i = 0, len = rows.length; i < len; ++i){ + row = rows[i]; + lrow = lrows[i]; + row.rowIndex = i; + lrow.rowIndex = i; + if(!skipStripe){ + row.className = row.className.replace(this.rowClsRe, ' '); + lrow.className = lrow.className.replace(this.rowClsRe, ' '); + if ((i + 1) % 2 === 0){ + row.className += ' x-grid3-row-alt'; + lrow.className += ' x-grid3-row-alt'; + } + } + if(this.syncHeights){ + var el1 = Ext.get(row), + el2 = Ext.get(lrow), + h1 = el1.getHeight(), + h2 = el2.getHeight(); + + if(h1 > h2){ + el2.setHeight(h1); + }else if(h2 > h1){ + el1.setHeight(h2); + } + } + } + if(startRow === 0){ + Ext.fly(rows[0]).addClass(this.firstRowCls); + Ext.fly(lrows[0]).addClass(this.firstRowCls); + } + Ext.fly(rows[rows.length - 1]).addClass(this.lastRowCls); + Ext.fly(lrows[lrows.length - 1]).addClass(this.lastRowCls); + }, + + afterRender : function(){ + if(!this.ds || !this.cm){ + return; + } + var bd = this.renderRows() || [' ', ' ']; + this.mainBody.dom.innerHTML = bd[0]; + this.lockedBody.dom.innerHTML = bd[1]; + this.processRows(0, true); + if(this.deferEmptyText !== true){ + this.applyEmptyText(); + } + }, + + renderUI : function(){ + var header = this.renderHeaders(); + var body = this.templates.body.apply({rows:' '}); + var html = this.templates.master.apply({ + body: body, + header: header[0], + ostyle: 'width:'+this.getOffsetWidth()+';', + bstyle: 'width:'+this.getTotalWidth()+';', + lockedBody: body, + lockedHeader: header[1], + lstyle: 'width:'+this.getLockedWidth()+';' + }); + var g = this.grid; + g.getGridEl().dom.innerHTML = html; + this.initElements(); + Ext.fly(this.innerHd).on('click', this.handleHdDown, this); + Ext.fly(this.lockedInnerHd).on('click', this.handleHdDown, this); + this.mainHd.on({ + scope: this, + mouseover: this.handleHdOver, + mouseout: this.handleHdOut, + mousemove: this.handleHdMove + }); + this.lockedHd.on({ + scope: this, + mouseover: this.handleHdOver, + mouseout: this.handleHdOut, + mousemove: this.handleHdMove + }); + this.scroller.on('scroll', this.syncScroll, this); + if(g.enableColumnResize !== false){ + this.splitZone = new Ext.grid.GridView.SplitDragZone(g, this.mainHd.dom); + this.splitZone.setOuterHandleElId(Ext.id(this.lockedHd.dom)); + this.splitZone.setOuterHandleElId(Ext.id(this.mainHd.dom)); + } + if(g.enableColumnMove){ + this.columnDrag = new Ext.grid.GridView.ColumnDragZone(g, this.innerHd); + this.columnDrag.setOuterHandleElId(Ext.id(this.lockedInnerHd)); + this.columnDrag.setOuterHandleElId(Ext.id(this.innerHd)); + this.columnDrop = new Ext.grid.HeaderDropZone(g, this.mainHd.dom); + } + if(g.enableHdMenu !== false){ + this.hmenu = new Ext.menu.Menu({id: g.id + '-hctx'}); + this.hmenu.add( + {itemId: 'asc', text: this.sortAscText, cls: 'xg-hmenu-sort-asc'}, + {itemId: 'desc', text: this.sortDescText, cls: 'xg-hmenu-sort-desc'} + ); + if(this.grid.enableColLock !== false){ + this.hmenu.add('-', + {itemId: 'lock', text: this.lockText, cls: 'xg-hmenu-lock'}, + {itemId: 'unlock', text: this.unlockText, cls: 'xg-hmenu-unlock'} + ); + } + if(g.enableColumnHide !== false){ + this.colMenu = new Ext.menu.Menu({id:g.id + '-hcols-menu'}); + this.colMenu.on({ + scope: this, + beforeshow: this.beforeColMenuShow, + itemclick: this.handleHdMenuClick + }); + this.hmenu.add('-', { + itemId:'columns', + hideOnClick: false, + text: this.columnsText, + menu: this.colMenu, + iconCls: 'x-cols-icon' + }); + } + this.hmenu.on('itemclick', this.handleHdMenuClick, this); + } + if(g.trackMouseOver){ + this.mainBody.on({ + scope: this, + mouseover: this.onRowOver, + mouseout: this.onRowOut + }); + this.lockedBody.on({ + scope: this, + mouseover: this.onRowOver, + mouseout: this.onRowOut + }); + } + + if(g.enableDragDrop || g.enableDrag){ + this.dragZone = new Ext.grid.GridDragZone(g, { + ddGroup : g.ddGroup || 'GridDD' + }); + } + this.updateHeaderSortState(); + }, + + layout : function(){ + if(!this.mainBody){ + return; + } + var g = this.grid; + var c = g.getGridEl(); + var csize = c.getSize(true); + var vw = csize.width; + if(!g.hideHeaders && (vw < 20 || csize.height < 20)){ + return; + } + this.syncHeaderHeight(); + if(g.autoHeight){ + this.scroller.dom.style.overflow = 'visible'; + this.lockedScroller.dom.style.overflow = 'visible'; + if(Ext.isWebKit){ + this.scroller.dom.style.position = 'static'; + this.lockedScroller.dom.style.position = 'static'; + } + }else{ + this.el.setSize(csize.width, csize.height); + var hdHeight = this.mainHd.getHeight(); + var vh = csize.height - (hdHeight); + } + this.updateLockedWidth(); + if(this.forceFit){ + if(this.lastViewWidth != vw){ + this.fitColumns(false, false); + this.lastViewWidth = vw; + } + }else { + this.autoExpand(); + this.syncHeaderScroll(); + } + this.onLayout(vw, vh); + }, + + getOffsetWidth : function() { + return (this.cm.getTotalWidth() - this.cm.getTotalLockedWidth() + this.getScrollOffset()) + 'px'; + }, + + renderHeaders : function(){ + var cm = this.cm, + ts = this.templates, + ct = ts.hcell, + cb = [], lcb = [], + p = {}, + len = cm.getColumnCount(), + last = len - 1; + for(var i = 0; i < len; i++){ + p.id = cm.getColumnId(i); + p.value = cm.getColumnHeader(i) || ''; + p.style = this.getColumnStyle(i, true); + p.tooltip = this.getColumnTooltip(i); + p.css = (i === 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '')) + + (cm.config[i].headerCls ? ' ' + cm.config[i].headerCls : ''); + if(cm.config[i].align == 'right'){ + p.istyle = 'padding-right:16px'; + } else { + delete p.istyle; + } + if(cm.isLocked(i)){ + lcb[lcb.length] = ct.apply(p); + }else{ + cb[cb.length] = ct.apply(p); + } + } + return [ts.header.apply({cells: cb.join(''), tstyle:'width:'+this.getTotalWidth()+';'}), + ts.header.apply({cells: lcb.join(''), tstyle:'width:'+this.getLockedWidth()+';'})]; + }, + + updateHeaders : function(){ + var hd = this.renderHeaders(); + this.innerHd.firstChild.innerHTML = hd[0]; + this.innerHd.firstChild.style.width = this.getOffsetWidth(); + this.innerHd.firstChild.firstChild.style.width = this.getTotalWidth(); + this.lockedInnerHd.firstChild.innerHTML = hd[1]; + var lw = this.getLockedWidth(); + this.lockedInnerHd.firstChild.style.width = lw; + this.lockedInnerHd.firstChild.firstChild.style.width = lw; + }, + + getResolvedXY : function(resolved){ + if(!resolved){ + return null; + } + var c = resolved.cell, r = resolved.row; + return c ? Ext.fly(c).getXY() : [this.scroller.getX(), Ext.fly(r).getY()]; + }, + + syncFocusEl : function(row, col, hscroll){ + Ext.ux.grid.LockingGridView.superclass.syncFocusEl.call(this, row, col, col < this.cm.getLockedCount() ? false : hscroll); + }, + + ensureVisible : function(row, col, hscroll){ + return Ext.ux.grid.LockingGridView.superclass.ensureVisible.call(this, row, col, col < this.cm.getLockedCount() ? false : hscroll); + }, + + insertRows : function(dm, firstRow, lastRow, isUpdate){ + var last = dm.getCount() - 1; + if(!isUpdate && firstRow === 0 && lastRow >= last){ + this.refresh(); + }else{ + if(!isUpdate){ + this.fireEvent('beforerowsinserted', this, firstRow, lastRow); + } + var html = this.renderRows(firstRow, lastRow), + before = this.getRow(firstRow); + if(before){ + if(firstRow === 0){ + this.removeRowClass(0, this.firstRowCls); + } + Ext.DomHelper.insertHtml('beforeBegin', before, html[0]); + before = this.getLockedRow(firstRow); + Ext.DomHelper.insertHtml('beforeBegin', before, html[1]); + }else{ + this.removeRowClass(last - 1, this.lastRowCls); + Ext.DomHelper.insertHtml('beforeEnd', this.mainBody.dom, html[0]); + Ext.DomHelper.insertHtml('beforeEnd', this.lockedBody.dom, html[1]); + } + if(!isUpdate){ + this.fireEvent('rowsinserted', this, firstRow, lastRow); + this.processRows(firstRow); + }else if(firstRow === 0 || firstRow >= last){ + this.addRowClass(firstRow, firstRow === 0 ? this.firstRowCls : this.lastRowCls); + } + } + this.syncFocusEl(firstRow); + }, + + getColumnStyle : function(col, isHeader){ + var style = !isHeader ? this.cm.config[col].cellStyle || this.cm.config[col].css || '' : this.cm.config[col].headerStyle || ''; + style += 'width:'+this.getColumnWidth(col)+';'; + if(this.cm.isHidden(col)){ + style += 'display:none;'; + } + var align = this.cm.config[col].align; + if(align){ + style += 'text-align:'+align+';'; + } + return style; + }, + + getLockedWidth : function() { + return this.cm.getTotalLockedWidth() + 'px'; + }, + + getTotalWidth : function() { + return (this.cm.getTotalWidth() - this.cm.getTotalLockedWidth()) + 'px'; + }, + + getColumnData : function(){ + var cs = [], cm = this.cm, colCount = cm.getColumnCount(); + for(var i = 0; i < colCount; i++){ + var name = cm.getDataIndex(i); + cs[i] = { + name : (!Ext.isDefined(name) ? this.ds.fields.get(i).name : name), + renderer : cm.getRenderer(i), + id : cm.getColumnId(i), + style : this.getColumnStyle(i), + locked : cm.isLocked(i) + }; + } + return cs; + }, + + renderBody : function(){ + var markup = this.renderRows() || [' ', ' ']; + return [this.templates.body.apply({rows: markup[0]}), this.templates.body.apply({rows: markup[1]})]; + }, + + refreshRow : function(record){ + Ext.ux.grid.LockingGridView.superclass.refreshRow.call(this, record); + var index = Ext.isNumber(record) ? record : this.ds.indexOf(record); + this.getLockedRow(index).rowIndex = index; + }, + + refresh : function(headersToo){ + this.fireEvent('beforerefresh', this); + this.grid.stopEditing(true); + var result = this.renderBody(); + this.mainBody.update(result[0]).setWidth(this.getTotalWidth()); + this.lockedBody.update(result[1]).setWidth(this.getLockedWidth()); + if(headersToo === true){ + this.updateHeaders(); + this.updateHeaderSortState(); + } + this.processRows(0, true); + this.layout(); + this.applyEmptyText(); + this.fireEvent('refresh', this); + }, + + onDenyColumnLock : function(){ + + }, + + initData : function(ds, cm){ + if(this.cm){ + this.cm.un('columnlockchange', this.onColumnLock, this); + } + Ext.ux.grid.LockingGridView.superclass.initData.call(this, ds, cm); + if(this.cm){ + this.cm.on('columnlockchange', this.onColumnLock, this); + } + }, + + onColumnLock : function(){ + this.refresh(true); + }, + + handleHdMenuClick : function(item){ + var index = this.hdCtxIndex, + cm = this.cm, + id = item.getItemId(), + llen = cm.getLockedCount(); + switch(id){ + case 'lock': + if(cm.getColumnCount(true) <= llen + 1){ + this.onDenyColumnLock(); + return; + } + if(llen != index){ + cm.setLocked(index, true, true); + cm.moveColumn(index, llen); + this.grid.fireEvent('columnmove', index, llen); + }else{ + cm.setLocked(index, true); + } + break; + case 'unlock': + if(llen - 1 != index){ + cm.setLocked(index, false, true); + cm.moveColumn(index, llen - 1); + this.grid.fireEvent('columnmove', index, llen - 1); + }else{ + cm.setLocked(index, false); + } + break; + default: + return Ext.ux.grid.LockingGridView.superclass.handleHdMenuClick.call(this, item); + } + return true; + }, + + handleHdDown : function(e, t){ + Ext.ux.grid.LockingGridView.superclass.handleHdDown.call(this, e, t); + if(this.grid.enableColLock !== false){ + if(Ext.fly(t).hasClass('x-grid3-hd-btn')){ + var hd = this.findHeaderCell(t), + index = this.getCellIndex(hd), + ms = this.hmenu.items, cm = this.cm; + ms.get('lock').setDisabled(cm.isLocked(index)); + ms.get('unlock').setDisabled(!cm.isLocked(index)); + } + } + }, + + syncHeaderHeight: function(){ + this.innerHd.firstChild.firstChild.style.height = 'auto'; + this.lockedInnerHd.firstChild.firstChild.style.height = 'auto'; + var hd = this.innerHd.firstChild.firstChild.offsetHeight, + lhd = this.lockedInnerHd.firstChild.firstChild.offsetHeight, + height = (lhd > hd ? lhd : hd) + 'px'; + this.innerHd.firstChild.firstChild.style.height = height; + this.lockedInnerHd.firstChild.firstChild.style.height = height; + }, + + updateLockedWidth: function(){ + var lw = this.cm.getTotalLockedWidth(), + tw = this.cm.getTotalWidth() - lw, + csize = this.grid.getGridEl().getSize(true), + lp = Ext.isBorderBox ? 0 : this.lockedBorderWidth, + rp = Ext.isBorderBox ? 0 : this.rowBorderWidth, + vw = (csize.width - lw - lp - rp) + 'px', + so = this.getScrollOffset(); + if(!this.grid.autoHeight){ + var vh = (csize.height - this.mainHd.getHeight()) + 'px'; + this.lockedScroller.dom.style.height = vh; + this.scroller.dom.style.height = vh; + } + this.lockedWrap.dom.style.width = (lw + rp) + 'px'; + this.scroller.dom.style.width = vw; + this.mainWrap.dom.style.left = (lw + lp + rp) + 'px'; + if(this.innerHd){ + this.lockedInnerHd.firstChild.style.width = lw + 'px'; + this.lockedInnerHd.firstChild.firstChild.style.width = lw + 'px'; + this.innerHd.style.width = vw; + this.innerHd.firstChild.style.width = (tw + rp + so) + 'px'; + this.innerHd.firstChild.firstChild.style.width = tw + 'px'; + } + if(this.mainBody){ + this.lockedBody.dom.style.width = (lw + rp) + 'px'; + this.mainBody.dom.style.width = (tw + rp) + 'px'; + } + } +}); + +Ext.ux.grid.LockingColumnModel = Ext.extend(Ext.grid.ColumnModel, { + /** + * Returns true if the given column index is currently locked + * @param {Number} colIndex The column index + * @return {Boolean} True if the column is locked + */ + isLocked : function(colIndex){ + return this.config[colIndex].locked === true; + }, + + /** + * Locks or unlocks a given column + * @param {Number} colIndex The column index + * @param {Boolean} value True to lock, false to unlock + * @param {Boolean} suppressEvent Pass false to cause the columnlockchange event not to fire + */ + setLocked : function(colIndex, value, suppressEvent){ + if (this.isLocked(colIndex) == value) { + return; + } + this.config[colIndex].locked = value; + if (!suppressEvent) { + this.fireEvent('columnlockchange', this, colIndex, value); + } + }, + + /** + * Returns the total width of all locked columns + * @return {Number} The width of all locked columns + */ + getTotalLockedWidth : function(){ + var totalWidth = 0; + for (var i = 0, len = this.config.length; i < len; i++) { + if (this.isLocked(i) && !this.isHidden(i)) { + totalWidth += this.getColumnWidth(i); + } + } + + return totalWidth; + }, + + /** + * Returns the total number of locked columns + * @return {Number} The number of locked columns + */ + getLockedCount : function() { + var len = this.config.length; + + for (var i = 0; i < len; i++) { + if (!this.isLocked(i)) { + return i; + } + } + + //if we get to this point all of the columns are locked so we return the total + return len; + }, + + /** + * Moves a column from one position to another + * @param {Number} oldIndex The current column index + * @param {Number} newIndex The destination column index + */ + moveColumn : function(oldIndex, newIndex){ + var oldLocked = this.isLocked(oldIndex), + newLocked = this.isLocked(newIndex); + + if (oldIndex < newIndex && oldLocked && !newLocked) { + this.setLocked(oldIndex, false, true); + } else if (oldIndex > newIndex && !oldLocked && newLocked) { + this.setLocked(oldIndex, true, true); + } + + Ext.ux.grid.LockingColumnModel.superclass.moveColumn.apply(this, arguments); + } +});