945 lines
33 KiB
JavaScript
945 lines
33 KiB
JavaScript
/*
|
|
This file is part of Ext JS 3.4
|
|
|
|
Copyright (c) 2011-2013 Sencha Inc
|
|
|
|
Contact: http://www.sencha.com/contact
|
|
|
|
GNU General Public License Usage
|
|
This file may be used under the terms of the GNU General Public License version 3.0 as
|
|
published by the Free Software Foundation and appearing in the file LICENSE included in the
|
|
packaging of this file.
|
|
|
|
Please review the following information to ensure the GNU General Public License version 3.0
|
|
requirements will be met: http://www.gnu.org/copyleft/gpl.html.
|
|
|
|
If you are unsure which license is appropriate for your use, please contact the sales department
|
|
at http://www.sencha.com/contact.
|
|
|
|
Build date: 2013-04-03 15:07:25
|
|
*/
|
|
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.masterTpl) {
|
|
ts.masterTpl = 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 el = Ext.get(this.grid.getGridEl().dom.firstChild),
|
|
lockedWrap = el.child('div.x-grid3-locked'),
|
|
lockedHd = lockedWrap.child('div.x-grid3-header'),
|
|
lockedScroller = lockedWrap.child('div.x-grid3-scroller'),
|
|
mainWrap = el.child('div.x-grid3-viewport'),
|
|
mainHd = mainWrap.child('div.x-grid3-header'),
|
|
scroller = mainWrap.child('div.x-grid3-scroller');
|
|
|
|
if (this.grid.hideHeaders) {
|
|
lockedHd.setDisplayed(false);
|
|
mainHd.setDisplayed(false);
|
|
}
|
|
|
|
if(this.forceFit){
|
|
scroller.setStyle('overflow-x', 'hidden');
|
|
}
|
|
|
|
Ext.apply(this, {
|
|
el : el,
|
|
mainWrap: mainWrap,
|
|
mainHd : mainHd,
|
|
innerHd : mainHd.dom.firstChild,
|
|
scroller: scroller,
|
|
mainBody: scroller.child('div.x-grid3-body'),
|
|
focusEl : scroller.child('a'),
|
|
resizeMarker: el.child('div.x-grid3-resize-marker'),
|
|
resizeProxy : el.child('div.x-grid3-resize-proxy'),
|
|
lockedWrap: lockedWrap,
|
|
lockedHd: lockedHd,
|
|
lockedScroller: lockedScroller,
|
|
lockedBody: lockedScroller.child('div.x-grid3-body'),
|
|
lockedInnerHd: lockedHd.child('div.x-grid3-header-inner', true)
|
|
});
|
|
|
|
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 lockedLen = this.cm.getLockedCount();
|
|
if(col < lockedLen){
|
|
return this.getLockedRow(row).getElementsByTagName('td')[col];
|
|
}
|
|
return Ext.ux.grid.LockingGridView.superclass.getCell.call(this, row, col - lockedLen);
|
|
},
|
|
|
|
getHeaderCell : function(index){
|
|
var lockedLen = this.cm.getLockedCount();
|
|
if(index < lockedLen){
|
|
return this.lockedHd.dom.getElementsByTagName('td')[index];
|
|
}
|
|
return Ext.ux.grid.LockingGridView.superclass.getHeaderCell.call(this, index - lockedLen);
|
|
},
|
|
|
|
addRowClass : function(row, cls){
|
|
var lockedRow = this.getLockedRow(row);
|
|
if(lockedRow){
|
|
this.fly(lockedRow).addClass(cls);
|
|
}
|
|
Ext.ux.grid.LockingGridView.superclass.addRowClass.call(this, row, cls);
|
|
},
|
|
|
|
removeRowClass : function(row, cls){
|
|
var lockedRow = this.getLockedRow(row);
|
|
if(lockedRow){
|
|
this.fly(lockedRow).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 lockedBody = this.lockedBody.dom,
|
|
rowIndex = firstRow;
|
|
for(; rowIndex <= lastRow; rowIndex++){
|
|
Ext.removeNode(lockedBody.childNodes[firstRow]);
|
|
}
|
|
Ext.ux.grid.LockingGridView.superclass.removeRows.call(this, firstRow, lastRow);
|
|
},
|
|
|
|
syncScroll : function(e){
|
|
this.lockedScroller.dom.scrollTop = this.scroller.dom.scrollTop;
|
|
Ext.ux.grid.LockingGridView.superclass.syncScroll.call(this, e);
|
|
},
|
|
|
|
updateSortIcon : function(col, dir){
|
|
var sortClasses = this.sortClasses,
|
|
lockedHeaders = this.lockedHd.select('td').removeClass(sortClasses),
|
|
headers = this.mainHd.select('td').removeClass(sortClasses),
|
|
lockedLen = this.cm.getLockedCount(),
|
|
cls = sortClasses[dir == 'DESC' ? 1 : 0];
|
|
|
|
if(col < lockedLen){
|
|
lockedHeaders.item(col).addClass(cls);
|
|
}else{
|
|
headers.item(col - lockedLen).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';
|
|
}
|
|
}
|
|
this.syncRowHeights(row, lrow);
|
|
}
|
|
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);
|
|
},
|
|
|
|
syncRowHeights: function(row1, row2){
|
|
if(this.syncHeights){
|
|
var el1 = Ext.get(row1),
|
|
el2 = Ext.get(row2),
|
|
h1 = el1.getHeight(),
|
|
h2 = el2.getHeight();
|
|
|
|
if(h1 > h2){
|
|
el2.setHeight(h1);
|
|
}else if(h2 > h1){
|
|
el1.setHeight(h2);
|
|
}
|
|
}
|
|
},
|
|
|
|
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();
|
|
}
|
|
this.grid.fireEvent('viewready', this.grid);
|
|
},
|
|
|
|
renderUI : function(){
|
|
var templates = this.templates,
|
|
header = this.renderHeaders(),
|
|
body = templates.body.apply({rows:' '});
|
|
|
|
return templates.masterTpl.apply({
|
|
body : body,
|
|
header: header[0],
|
|
ostyle: 'width:' + this.getOffsetWidth() + ';',
|
|
bstyle: 'width:' + this.getTotalWidth() + ';',
|
|
lockedBody: body,
|
|
lockedHeader: header[1],
|
|
lstyle: 'width:'+this.getLockedWidth()+';'
|
|
});
|
|
},
|
|
|
|
afterRenderUI: function(){
|
|
var g = this.grid;
|
|
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: 'sortSep',
|
|
xtype: 'menuseparator'
|
|
},
|
|
{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),
|
|
scope : cm.getRendererScope(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){
|
|
var store = this.ds,
|
|
colCount = this.cm.getColumnCount(),
|
|
columns = this.getColumnData(),
|
|
last = colCount - 1,
|
|
cls = ['x-grid3-row'],
|
|
rowParams = {
|
|
tstyle: String.format("width: {0};", this.getTotalWidth())
|
|
},
|
|
lockedRowParams = {
|
|
tstyle: String.format("width: {0};", this.getLockedWidth())
|
|
},
|
|
colBuffer = [],
|
|
lockedColBuffer = [],
|
|
cellTpl = this.templates.cell,
|
|
rowIndex,
|
|
row,
|
|
lockedRow,
|
|
column,
|
|
meta,
|
|
css,
|
|
i;
|
|
|
|
if (Ext.isNumber(record)) {
|
|
rowIndex = record;
|
|
record = store.getAt(rowIndex);
|
|
} else {
|
|
rowIndex = store.indexOf(record);
|
|
}
|
|
|
|
if (!record || rowIndex < 0) {
|
|
return;
|
|
}
|
|
|
|
for (i = 0; i < colCount; i++) {
|
|
column = columns[i];
|
|
|
|
if (i == 0) {
|
|
css = 'x-grid3-cell-first';
|
|
} else {
|
|
css = (i == last) ? 'x-grid3-cell-last ' : '';
|
|
}
|
|
|
|
meta = {
|
|
id: column.id,
|
|
style: column.style,
|
|
css: css,
|
|
attr: "",
|
|
cellAttr: ""
|
|
};
|
|
|
|
meta.value = column.renderer.call(column.scope, record.data[column.name], meta, record, rowIndex, i, store);
|
|
|
|
if (Ext.isEmpty(meta.value)) {
|
|
meta.value = ' ';
|
|
}
|
|
|
|
if (this.markDirty && record.dirty && typeof record.modified[column.name] != 'undefined') {
|
|
meta.css += ' x-grid3-dirty-cell';
|
|
}
|
|
|
|
if (column.locked) {
|
|
lockedColBuffer[i] = cellTpl.apply(meta);
|
|
} else {
|
|
colBuffer[i] = cellTpl.apply(meta);
|
|
}
|
|
}
|
|
|
|
row = this.getRow(rowIndex);
|
|
row.className = '';
|
|
lockedRow = this.getLockedRow(rowIndex);
|
|
lockedRow.className = '';
|
|
|
|
if (this.grid.stripeRows && ((rowIndex + 1) % 2 === 0)) {
|
|
cls.push('x-grid3-row-alt');
|
|
}
|
|
|
|
if (this.getRowClass) {
|
|
rowParams.cols = colCount;
|
|
cls.push(this.getRowClass(record, rowIndex, rowParams, store));
|
|
}
|
|
|
|
// Unlocked rows
|
|
this.fly(row).addClass(cls).setStyle(rowParams.tstyle);
|
|
rowParams.cells = colBuffer.join("");
|
|
row.innerHTML = this.templates.rowInner.apply(rowParams);
|
|
|
|
// Locked rows
|
|
this.fly(lockedRow).addClass(cls).setStyle(lockedRowParams.tstyle);
|
|
lockedRowParams.cells = lockedColBuffer.join("");
|
|
lockedRow.innerHTML = this.templates.rowInner.apply(lockedRowParams);
|
|
lockedRow.rowIndex = rowIndex;
|
|
this.syncRowHeights(row, lockedRow);
|
|
this.fireEvent('rowupdated', this, rowIndex, record);
|
|
},
|
|
|
|
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 undefined;
|
|
}
|
|
cm.setLocked(index, true, llen != index);
|
|
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(){
|
|
var hrow = Ext.fly(this.innerHd).child('tr', true),
|
|
lhrow = Ext.fly(this.lockedInnerHd).child('tr', true);
|
|
|
|
hrow.style.height = 'auto';
|
|
lhrow.style.height = 'auto';
|
|
var hd = hrow.offsetHeight,
|
|
lhd = lhrow.offsetHeight,
|
|
height = Math.max(lhd, hd) + 'px';
|
|
|
|
hrow.style.height = height;
|
|
lhrow.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 = Math.max(csize.width - lw - lp - rp, 0) + 'px',
|
|
so = this.getScrollOffset();
|
|
if(!this.grid.autoHeight){
|
|
var vh = Math.max(csize.height - this.mainHd.getHeight(), 0) + '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);
|
|
}
|
|
});
|