Code:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" type="text/css" href="ext/resources/css/ext-all.css">
<script type="text/javascript" src="ext/adapter/ext/ext-base.js"></script>
<script type="text/javascript" src="ext/ext-all-debug.js"></script>
<script type="text/javascript" src="extUX/LockingGridView.js"></script>
<title id="page-title">Locked Grid</title>
<script type="text/javascript">
Ext.BLANK_IMAGE_URL = 'ext/resources/images/default/s.gif';
Ext.onReady(function(){
// sample static data for the store
var myData = [
['3m Co',71.72,0.02,0.03,'9/1 12:00am'],
['Alcoa Inc',29.01,0.42,1.47,'9/1 12:00am'],
['Altria Group Inc',83.81,0.28,0.34,'9/1 12:00am'],
['American Express Company',52.55,0.01,0.02,'9/1 12:00am'],
['American International Group, Inc.',64.13,0.31,0.49,'9/1 12:00am'],
['AT&T Inc.',31.61,-0.48,-1.54,'9/1 12:00am'],
['Boeing Co.',75.43,0.53,0.71,'9/1 12:00am'],
['Caterpillar Inc.',67.27,0.92,1.39,'9/1 12:00am'],
['Citigroup, Inc.',49.37,0.02,0.04,'9/1 12:00am'],
['E.I. du Pont de Nemours and Company',40.48,0.51,1.28,'9/1 12:00am'],
['Exxon Mobil Corp',68.1,-0.43,-0.64,'9/1 12:00am'],
['General Electric Company',34.14,-0.08,-0.23,'9/1 12:00am'],
['General Motors Corporation',30.27,1.09,3.74,'9/1 12:00am'],
['Hewlett-Packard Co.',36.53,-0.03,-0.08,'9/1 12:00am'],
['Honeywell Intl Inc',38.77,0.05,0.13,'9/1 12:00am'],
['Intel Corporation',19.88,0.31,1.58,'9/1 12:00am'],
['International Business Machines',81.41,0.44,0.54,'9/1 12:00am'],
['Johnson & Johnson',64.72,0.06,0.09,'9/1 12:00am'],
['JP Morgan & Chase & Co',45.73,0.07,0.15,'9/1 12:00am'],
['McDonald\'s Corporation',36.76,0.86,2.40,'9/1 12:00am'],
['Merck & Co., Inc.',40.96,0.41,1.01,'9/1 12:00am'],
['Microsoft Corporation',25.84,0.14,0.54,'9/1 12:00am'],
['Pfizer Inc',27.96,0.4,1.45,'9/1 12:00am'],
['The Coca-Cola Company',45.07,0.26,0.58,'9/1 12:00am'],
['The Home Depot, Inc.',34.64,0.35,1.02,'9/1 12:00am'],
['The Procter & Gamble Company',61.91,0.01,0.02,'9/1 12:00am'],
['United Technologies Corporation',63.26,0.55,0.88,'9/1 12:00am'],
['Verizon Communications',35.57,0.39,1.11,'9/1 12:00am'],
['Wal-Mart Stores, Inc.',45.45,0.73,1.63,'9/1 12:00am']
];
/**
* Custom function used for column renderer
* @param {Object} val
*/
function change(val){
if(val > 0){
return '<span style="color:green;">' + val + '</span>';
}else if(val < 0){
return '<span style="color:red;">' + val + '</span>';
}
return val;
}
/**
* Custom function used for column renderer
* @param {Object} val
*/
function pctChange(val){
if(val > 0){
return '<span style="color:green;">' + val + '%</span>';
}else if(val < 0){
return '<span style="color:red;">' + val + '%</span>';
}
return val;
}
// create the data store
var store = new Ext.data.ArrayStore({
fields: [
{name: 'company'},
{name: 'price', type: 'float'},
{name: 'change', type: 'float'},
{name: 'pctChange', type: 'float'},
{name: 'lastChange', type: 'date', dateFormat: 'n/j h:ia'}
],
data: myData
});
// create the Grid
// To use locking functionality we must explicitly specify the LockingColumnModel and the LockingGridView
var grid = new Ext.grid.GridPanel({
store: store,
colModel: new Ext.ux.grid.LockingColumnModel([
{header: 'Company', width: 160, sortable: true, dataIndex: 'company', locked: true, id:'company'},
{header: 'Price', width: 85, sortable: true, renderer: 'usMoney', dataIndex: 'price'},
{header: 'Change', width: 85, sortable: true, renderer: change, dataIndex: 'change'},
{header: '% Change', width: 85, sortable: true, renderer: pctChange, dataIndex: 'pctChange'},
{header: 'Last Updated', width: 95, sortable: true, renderer: Ext.util.Format.dateRenderer('m/d/Y'), dataIndex: 'lastChange'}
]),
stripeRows: true,
height: 350,
width: 500,
title: 'Locking Array Grid',
view: new Ext.ux.grid.LockingGridView()
});
// render the grid to the specified div in the page
grid.render(Ext.getBody());
});
</script>
</head>
<body>
</body>
</html>
Here is the LockingGridView.js file I have in my local:
Code:
/*!
* Ext JS Library 3.2.1
* Copyright(c) 2006-2010 Ext JS, Inc.
* [email protected]
* 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 aren't predictable.
*/
syncHeights: false,
initTemplates : function(){
var ts = this.templates || {};
if (!ts.master) {
ts.master = new Ext.Template(
'<div class="x-grid3" hidefocus="true">',
'<div class="x-grid3-locked">',
'<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>',
'<div class="x-grid3-scroller"><div class="x-grid3-body" style="{lstyle}">{lockedBody}</div><div class="x-grid3-scroll-spacer"></div></div>',
'</div>',
'<div class="x-grid3-viewport x-grid3-unlocked">',
'<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>',
'<div class="x-grid3-scroller"><div class="x-grid3-body" style="{bstyle}">{body}</div><a href="#" class="x-grid3-focus" tabIndex="-1"></a></div>',
'</div>',
'<div class="x-grid3-resize-marker"> </div>',
'<div class="x-grid3-resize-proxy"> </div>',
'</div>'
);
}
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;
}
cm.setLocked(index, true);
if(llen != index){
cm.moveColumn(index, llen);
this.grid.fireEvent('columnmove', index, llen);
}
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);
}
});
Here is the snapshot of the locking gridView when I run this code: