PDA

View Full Version : TreeGrid + LockingColumn Grid



lukefowell89
3 Dec 2010, 8:17 AM
I need to be able to have a "freeze pane" like on excel, on the first column of my treegrid! This tree grid is very complex and needs to be a treegrid.

I need to be able to add the functionality of the LockingGridView example with a treegrid. This is very difficult as the TreeGrid extends a GridPanel and LockingGridView extends GridView. But I need to get this to work.

Please could someone suggest a way of achieving this?

New component, make from scratch extending from? gridview, gridpanel, treegrid?

Make a plugin to do this?

Is it possible to extend my treegrid to allow this to work?

All I want is the concept of how to proceed with as many pointers as you can give me!

Thanks

lukefowell89
3 Dec 2010, 8:36 AM
I have also forgot to mention that we are using a special view already which we are overwriting so cannot simply add the locking gridview to "view".

Condor
4 Dec 2010, 1:29 AM
The easiest solution is probably to create a custom component based on a combination of LockingGridView and MaximGB's TreeGrid (this is not the TreeGrid that comes with Ext!).

lukefowell89
6 Dec 2010, 4:28 AM
Right, I have had a go at merging the 2 with some additions to try and provide the outcome I require.

I have worked my way through about 100 bugs along the way but feel I am starting to get somewhere.... until I hit an error I cant seem to figure out! Basically none of my data is being recieved by my grid. When i do this.hasRows i get false returned. When I entered the data and checked the store in console, it appeared to be there fine.

Not 100% sure how explain the problem fully, but here is my code, the problem is on line 151, when I am looking for a locked row.



Ext.namespace('Ext.ux.lf');

Ext.ux.lf.LockingTreeGridView = Ext.extend(Ext.grid.GridView,
{
expanded_icon_class : 'ux-maximgb-tg-elbow-minus',
collapsed_icon_class : 'ux-maximgb-tg-elbow-plus',

last_expanded_icon_class : 'ux-maximgb-tg-elbow-end-minus',
last_collapsed_icon_class : 'ux-maximgb-tg-elbow-end-plus',

nl_expanded_icon_class : 'ux-maximgb-tg-nl-minus',
nl_collapsed_icon_class : 'ux-maximgb-tg-nl-plus',

skip_width_update_class: 'ux-maximgb-tg-skip-width-update',

expanded_folder_class : 'ux-maximgb-tg-expanded-folder',
collapsed_folder_class : 'ux-maximgb-tg-collapsed-folder',

lockText : 'Lock',
unlockText : 'Unlock',
rowBorderWidth : 1,
lockedBorderWidth : 1,

syncHeights: false,


initTemplates : function()
{
var ts = this.templates || {};

if (!ts.row) {
ts.row = new Ext.Template(
'<div class="x-grid3-row ux-maximgb-tg-level-{level} ux-maximgb-tg-border {alt}" style="{tstyle} {display_style}">',
'<table class="x-grid3-row-table" border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
'<tbody>',
'<tr>{cells}</tr>',
(
this.enableRowBody ?
'<tr class="x-grid3-row-body-tr" style="{bodyStyle}">' +
'<td colspan="{cols}" class="x-grid3-body-cell" tabIndex="0" hidefocus="on">'+
'<div class="x-grid3-row-body">{body}</div>'+
'</td>'+
'</tr>'
:
''
),
'</tbody>',
'</table>',
'</div>'
);
}

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">&#160;</div>',
'<div class="x-grid3-resize-proxy">&#160;</div>',
'</div>'
);
}

if (!ts.mastercell) {
ts.mastercell = new Ext.Template(
'<td class="x-grid3-col x-grid3-cell x-grid3-td-{id} {css}" style="{style}" tabIndex="0" {cellAttr}>',
'<div class="ux-maximgb-tg-mastercell-wrap">', // This is for editor to place itself right
'{treeui}',
'<div class="x-grid3-cell-inner x-grid3-col-{id}" unselectable="on" {attr} style="padding-top:3px">{value}</div>',
'</div>',
'</td>'
);
}

if (!ts.treeui) {
ts.treeui = new Ext.Template(
'<div class="ux-maximgb-tg-uiwrap" style="width: {wrap_width}px">',
'{elbow_line}',
'<div style="left: {left}px" class="{cls}">&#160;</div>',
'</div>'
);
}

if (!ts.elbow_line) {
ts.elbow_line = new Ext.Template(
'<div style="left: {left}px" class="{cls}">&#160;</div>'
);
}

this.templates = ts;
Ext.ux.lf.LockingTreeGridView.superclass.initTemplates.call(this);
},

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){
if(col < 1){
return this.getLockedRow(row).getElementsByTagName('td')[col];
}
return Ext.ux.grid.LockingGridView.superclass.getCell.call(this, row, col - lockedLen);
},

getHeaderCell : function(index){
var lockedLen = 1;
if(index < lockedLen){
return this.lockedHd.dom.getElementsByTagName('td')[index];
}
return Ext.ux.lf.LockingTreeGridView.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 = 1,
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(columns, records, store, startRow, colCount, stripe){
var templates = this.templates;
var cell_template = templates.cell;
var row_template = templates.row;
var last = colCount-1;
var tstyle = 'width:'+this.getTotalWidth()+';';
var lstyle = 'width:'+this.getLockedWidth()+';';
var buffer = [];
var locked_buffer = [];
var column_buffer = [];
var locked_column_buffer = [];
var column;
var params = {};
var row_params = {};
var record;

for (var x = 0, len = records.length; x < len; x++) {

record = records[x];
var rowIndex = x + startRow;

var row_render_res = this.renderRow(record, rowIndex, colCount, store, this.cm.getTotalWidth());

if (row_render_res === false) {
for (var i = 0; i < colCount; i++) {

column= columns[i];
params.id = column.id;
params.css = i == 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '');
params.attr = params.cellAttr = "";
params.value = column.renderer.call(column.scope, record.data[column.name], params, record, rowIndex, i, store);
params.style = column.style;

if(Ext.isEmpty(params.value)){
params.value = "&#160;";
}
if(this.markDirty && record.dirty && typeof record.modified[column.name] !== 'undefined'){
params.css += ' x-grid3-dirty-cell';
}

if (column.id == this.grid.master_column_id) {
params.treeui = this.renderCellTreeUI(record, store);
cell_template = templates.mastercell;
}
else {
cell_template = templates.cell;
}

if(column.locked){
locked_column_buffer[locked_column_buffer.length] = cell_template.apply(params);
}
else {
column_buffer[column_buffer.length] = cell_template.apply(params);
}

}
}
else {
column_buffer.push(row_render_res);
}

var alt = [];
if (stripe && ((rowIndex+1) % 2 == 0)) {
alt[0] = "x-grid3-row-alt";
}
if (record.dirty) {
alt[1] = " x-grid3-dirty-row";
}
row_params.cols = colCount;
if(this.getRowClass){
alt[2] = this.getRowClass(r, rowIndex, rp, ds);
}
row_params.alt = alt.join(" ");
row_params.cells = column_buffer.join("");
row_params.tstyle = tstyle;
buffer[buffer.length] = row_template.apply(row_params);
row_params.cells = locked_column_buffer.join('');
row_params.tstyle = lstyle;
locked_buffer[locked_buffer.length] = row_template.apply(row_params);

if (!store.isVisibleNode(record)) {
row_params.display_style = 'display: none;';
}
else {
row_params.display_style = '';
}
row_params.level = store.getNodeDepth(record);

buffer[buffer.length] = row_template.apply(row_params);
}
return buffer.join(""), locked_buffer.join("") + "<div id=\"drop-pointer\" class=\"ux-maximgb-tg-drop-pointer\"/>";

},

renderCellTreeUI : function(record, store)
{
var template = this.templates.treeui,
line_template = this.templates.elbow_line,
template_data = {},
rec, parent,
depth = level = store.getNodeDepth(record);

template_data.elbow_line = '';
rec = record;
left = 0;

if (store.isLeafNode(rec)) {
template_data.elbow_line = line_template.apply({
left : level * 16 + 16,
cls : 'ux-maximgb-tg-elbow-active-folder ux-maximgb-tg-item'
});
} else {
template_data.elbow_line = line_template.apply({
left : level * 16 + 16,
cls : 'ux-maximgb-tg-elbow-active-folder ux-maximgb-tg-expanded-folder'
});
}

template_data.wrap_width = (depth + 1) * 16 + 16;
if (level > 0) {
while(level--) {
parent = store.getNodeParent(rec);
if (parent) {
if (store.hasNextSiblingNode(parent)) {
template_data.elbow_line =
line_template.apply({
left : level * 16,
cls : 'ux-maximgb-tg-elbow-line',
}) +
template_data.elbow_line;
}
else {
template_data.elbow_line =
line_template.apply({
left : level * 16,
cls : 'ux-maximgb-tg-elbow-empty',
}) +
template_data.elbow_line;
}
}
else {
throw [
"Tree inconsistency can't get level ",
level + 1,
" node(id=", rec.id, ") parent."
].join("");
}
rec = parent;
}
}
if (store.isLeafNode(record)) {
if (store.hasNextSiblingNode(record)) {
template_data.cls = 'ux-maximgb-tg-elbow';
}
else {
template_data.cls = 'ux-maximgb-tg-elbow-end';
}
}
else {
template_data.cls = 'ux-maximgb-tg-elbow-active ';
if (store.isExpandedNode(record)) {
if (store.hasNextSiblingNode(record)) {
template_data.cls += this.expanded_icon_class;
} else if (store.hasPrevSiblingNode(record)) {
template_data.cls += this.last_expanded_icon_class;
} else {
template_data.cls += this.nl_expanded_icon_class;
}
}
else {
if (store.hasNextSiblingNode(record)) {
template_data.cls += this.collapsed_icon_class;
} else if (store.hasPrevSiblingNode(record)) {
template_data.cls += this.last_collapsed_icon_class;
} else {
template_data.cls += this.nl_collapsed_icon_class;
}
}
}
template_data.left = 1 + depth * 16;

return template.apply(template_data);
},

renderRow : function(record, index, col_count, store, total_width)
{
return false;
},

afterRender : function()
{
Ext.ux.lf.LockingTreeGridView.superclass.afterRender.call(this);
if(!this.ds || !this.cm){
return;
}
var body = this.renderRows() || ['&#160;', '&#160;'];
this.mainBody.dom.innerHTML = body[0];
this.lockedBody.dom.innerHTML = body[1];
this.processRows(0, true);
if(this.deferEmptyText !== true){
this.applyEmptyText();
}
this.grid.fireEvent('viewready', this.grid);
this.updateAllColumnWidths();
},

renderUI : function()
{
var templates = this.templates,
header = this.renderHeaders(),
body = templates.body.apply({rows:'&#160;'});

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()+';'
});
},

getOffsetWidth : function()
{
return (this.cm.getTotalWidth() - this.cm.getColumnWidth(0) + this.getScrollOffset()) + 'px';
},

afterRenderUI: function()
{
var grid = 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(grid.enableColumnResize !== false){
this.splitZone = new Ext.grid.GridView.SplitDragZone(grid, this.mainHd.dom);
this.splitZone.setOuterHandleElId(Ext.id(this.lockedHd.dom));
this.splitZone.setOuterHandleElId(Ext.id(this.mainHd.dom));
}
if(grid.enableColumnMove){
this.columnDrag = new Ext.grid.GridView.ColumnDragZone(grid, this.innerHd);
this.columnDrag.setOuterHandleElId(Ext.id(this.lockedInnerHd));
this.columnDrag.setOuterHandleElId(Ext.id(this.innerHd));
this.columnDrop = new Ext.grid.HeaderDropZone(grid, this.mainHd.dom);
}
if(grid.enableHdMenu !== false){
this.hmenu = new Ext.menu.Menu({id: grid.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(grid.enableColumnHide !== false){
this.colMenu = new Ext.menu.Menu({id:grid.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(grid.trackMouseOver){
this.mainBody.on({
scope: this,
mouseover: this.onRowOver,
mouseout: this.onRowOut
});
this.lockedBody.on({
scope: this,
mouseover: this.onRowOver,
mouseout: this.onRowOut
});
}

if(grid.enableDragDrop || grid.enableDrag){
this.dragZone = new Ext.grid.GridDragZone(grid, {
ddGroup : grid.ddGroup || 'GridDD'
});
}
this.updateHeaderSortState();
},

layout : function(){
if(!this.mainBody){
return;
}
var grid = this.grid;
var grid_el = grid.getGridEl();
var cell_size = grid_el.getSize(true);
if(!grid.hideHeaders && (cell_size.width < 20 || cell_size.height < 20)){
return;
}

if(grid.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(cell_size.width, cell_size.height);
var hdHeight = this.mainHd.getHeight();
var cell_height = cell_size.height - (hdHeight);
}
this.updateLockedWidth();
if(this.forceFit){
if(this.lastViewWidth != cell_size.width){
this.fitColumns(false, false);
this.lastViewWidth = cell_size.width;
}
}else {
this.autoExpand();
this.syncHeaderScroll();
}
this.onLayout(cell_size.width, cell_height);
},

renderHeaders : function()
{
var column_model = this.cm,
templates = this.templates,
ct = templates.hcell,
cb = [], locked_cb = [],
params = {},
len = column_model.getColumnCount(),
last = len - 1;
for(var i = 0; i < len; i++)
{
params.id = column_model.getColumnId(i);
params.value = column_model.getColumnHeader(i) || '';
params.style = this.getColumnStyle(i, true);
params.tooltip = this.getColumnTooltip(i);
params.css = (i === 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '')) +
(column_model.config[i].headerCls ? ' ' + column_model.config[i].headerCls : '');
if(column_model.config[i].align == 'right'){
params.istyle = 'padding-right:16px';
} else {
delete params.istyle;
}
if(i == 0)
{
locked_cb[locked_cb.length] = ct.apply(params);
}
else
{
cb[cb.length] = ct.apply(params);
}
}
return [templates.header.apply({cells: cb.join(''), tstyle:'width:'+this.getTotalWidth()+';'}),
templates.header.apply({cells: locked_cb.join(''), tstyle:'width:'+this.getLockedWidth()+';'})];
},

updateHeaders : function()
{
var header = this.renderHeaders();
this.innerHd.firstChild.innerHTML = header[0];
this.innerHd.firstChild.style.width = this.getOffsetWidth();
this.innerHd.firstChild.firstChild.style.width = this.getTotalWidth();
this.lockedInnerHd.firstChild.innerHTML = header[1];
var locked_width = this.getLockedWidth();
this.lockedInnerHd.firstChild.style.width = locked_width;
this.lockedInnerHd.firstChild.firstChild.style.width = locked_width;
},

getResolvedXY : function(resolved){
if(!resolved){
return null;
}
var cell = resolved.cell, row = resolved.row;
return cell ? Ext.fly(cell).getXY() : [this.scroller.getX(), Ext.fly(row).getY()];
},

syncFocusEl : function(row, col, hscroll){
Ext.ux.lf.LockingTreeGridView.superclass.syncFocusEl.call(this, row, col, col < 1 ? false : hscroll);
},

ensureVisible : function(row, col, hscroll){
return Ext.ux.lf.LockingTreeGridView.superclass.ensureVisible.call(this, row, col, col < this.cm.getLockedCount() ? false : hscroll);
},

updateAllColumnWidths : function()
{
var total_width = this.getTotalWidth(),
column_length = this.cm.getColumnCount(),
widths = [],
length,
i;
for(i = 0; i < column_length; i++){
widths[i] = this.getColumnWidth(i);
}
this.innerHd.firstChild.style.width = this.getOffsetWidth();
this.innerHd.firstChild.firstChild.style.width = total_width;
this.mainBody.dom.style.width = total_width;
for(i = 0; i < column_length; i++){
var header = this.getHeaderCell(i);
header.style.width = widths[i];
}

var rows = this.getRows(), row, trow;
for(i = 0, len = rows.length; i < len; i++){
row = rows[i];
row.style.width = total_width;
if(row.firstChild){
row.firstChild.style.width = total_width;
total_row = row.firstChild.rows[0];
for (var j = 0; j < column_length && j < total_row.childNodes.length; j++) {
if (!Ext.fly(total_row.childNodes[j]).hasClass(this.skip_width_update_class)) {
total_row.childNodes[j].style.width = widths[j];
}
}
}
}

this.onAllColumnWidthsUpdated(widths, total_width);
},

updateColumnWidth : function(col, width)
{
var col_width = this.getColumnWidth(col);
var total_width = this.getTotalWidth();
this.innerHd.firstChild.style.width = this.getOffsetWidth();
this.innerHd.firstChild.firstChild.style.width = total_width;
this.mainBody.dom.style.width = total_width;
var header = this.getHeaderCell(col);
header.style.width = col_width;

var rows = this.getRows(), row;
for(var i = 0, len = rows.length; i < len; i++){
row = rows[i];
row.style.width = total_width;
if(row.firstChild){
row.firstChild.style.width = total_width;
if (col < row.firstChild.rows[0].childNodes.length) {
if (!Ext.fly(row.firstChild.rows[0].childNodes[col]).hasClass(this.skip_width_update_class)) {
row.firstChild.rows[0].childNodes[col].style.width = col_width;
}
}
}
}

this.onColumnWidthUpdated(col, col_width, total_width);
},

updateColumnHidden : function(col, hidden)
{
var total_width = this.getTotalWidth();
this.innerHd.firstChild.style.width = this.getOffsetWidth();
this.innerHd.firstChild.firstChild.style.width = total_width;
this.mainBody.dom.style.width = total_width;
var display = hidden ? 'none' : '';

var header = this.getHeaderCell(col);
header.style.display = display;

var rows = this.getRows(), row, cell;
for(var i = 0, len = rows.length; i < len; i++){
row = rows[i];
row.style.width = total_width;
if(row.firstChild){
row.firstChild.style.width = total_width;
if (col < row.firstChild.rows[0].childNodes.length) {
if (!Ext.fly(row.firstChild.rows[0].childNodes[col]).hasClass(this.skip_width_update_class)) {
row.firstChild.rows[0].childNodes[col].style.display = display;
}
}
}
}

this.onColumnHiddenUpdated(col, hidden, total_width);
delete this.lastViewWidth; // force recalc
this.layout();
},

processRows : function(startRow, skipStripe)
{
if(!this.store || this.store.getCount() < 1){
return;
}
var rows = this.getRows(),
locked_rows = this.getLockedRows(),
row, locked_row;

var processed_count = 0;

skipStripe = !this.grid.stripeRows; //skipStripe || !this.grid.stripeRows;
startRow = startRow || 0;

for(var i = 0, len = rows.length; i < len; ++i){
row = rows[i];
locked_row = locked_rows[i];
row.rowIndex = i;
locked_row.rowIndex = i;
if(!skipStripe){
row.className = row.className.replace(this.rowClsRe, ' ');
locked_row.className = locked_row.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(locked_rows[0]).addClass(this.firstRowCls);
}
Ext.fly(rows[rows.length - 1]).addClass(this.lastRowCls);
Ext.fly(locked_rows[locked_rows.length - 1]).addClass(this.lastRowCls);
},

ensureVisible : function(row, col, hscroll)
{
var ancestors, record = this.store.getAt(row);

if (!this.store.isVisibleNode(record))
{
ancestors = this.store.getNodeAncestors(record);
while (ancestors.length > 0)
{
record = ancestors.shift();
if (!this.store.isExpandedNode(record))
{
this.store.expandNode(record);
}
}
}

return Ext.ux.lf.LockingTreeGridView.superclass.ensureVisible.call(this, row, col, hscroll);
},

expandRow : function(record, skip_process)
{
var store = this.store,
i, len, row, pmel, children, index, child_index;

if (typeof record == 'number') {
index = record;
record = store.getAt(index);
}
else {
index = store.indexOf(record);
}

skip_process = skip_process || false;

row = this.getRow(index);
pmel = Ext.fly(row).child('.ux-maximgb-tg-elbow-active');
if (pmel) {
pmel.removeClass(this.collapsed_icon_class);
pmel.removeClass(this.last_collapsed_icon_class);
pmel.removeClass(this.nl_collapsed_icon_class);

if (ds.hasNextSiblingNode(record)) {
pmel.addClass(this.expanded_icon_class);
} else if (ds.hasPrevSiblingNode(record)) {
pmel.addClass(this.last_expanded_icon_class);
} else {
pmel.addClass(this.nl_expanded_icon_class);
}
}
pmel = Ext.fly(row).child('.ux-maximgb-tg-elbow-active-folder');
if (pmel) {
pmel.removeClass(this.collapsed_folder_class);
pmel.addClass(this.expanded_folder_class);
}
if (ds.isVisibleNode(record)) {
children = ds.getNodeChildren(record);
for (i = 0, len = children.length; i < len; i++) {
child_index = ds.indexOf(children[i]);
row = this.getRow(child_index);
row.style.display = 'block';
if (ds.isExpandedNode(children[i])) {
this.expandRow(child_index, true);
}
}
}
if (!skip_process) {
this.processRows(0);
}
//this.updateAllColumnWidths();
},

collapseRow : function(record, skip_process)
{
var ds = this.ds,
i, len, children, row, index, child_index;

if (typeof record == 'number') {
index = record;
record = ds.getAt(index);
}
else {
index = ds.indexOf(record);
}

skip_process = skip_process || false;

row = this.getRow(index);
pmel = Ext.fly(row).child('.ux-maximgb-tg-elbow-active');
if (pmel) {
pmel.removeClass(this.expanded_icon_class);
pmel.removeClass(this.last_expanded_icon_class);
pmel.removeClass(this.nl_expanded_icon_class);

if (ds.hasNextSiblingNode(record)) {
pmel.addClass(this.collapsed_icon_class);
} else if (ds.hasPrevSiblingNode(record)) {
pmel.addClass(this.last_collapsed_icon_class);
} else {
pmel.addClass(this.nl_collapsed_icon_class);
}
}
pmel = Ext.fly(row).child('.ux-maximgb-tg-elbow-active-folder');
if (pmel) {
pmel.removeClass(this.expanded_folder_class);
pmel.addClass(this.collapsed_folder_class);
}
children = ds.getNodeChildren(record);
for (i = 0, len = children.length; i < len; i++) {
child_index = ds.indexOf(children[i]);
row = this.getRow(child_index);
if (row.style.display != 'none') {
row.style.display = 'none';
this.collapseRow(child_index, true);
}
}
if (!skip_process) {
this.processRows(0);
}
},

initData : function(store, column_model)
{
if(this.cm){
this.cm.un('columnlockchange', this.onColumnLock, this);
}
Ext.ux.lf.LockingTreeGridView.superclass.initData.call(this, store, column_model);
if (this.store) {
this.store.un('expandnode', this.onStoreExpandNode, this);
this.store.un('collapsenode', this.onStoreCollapseNode, this);
}
if (store) {
store.on('expandnode', this.onStoreExpandNode, this);
store.on('collapsenode', this.onStoreCollapseNode, this);
}
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);
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.lf.LockingTreeGridView.superclass.handleHdMenuClick.call(this, item);
}
return true;
},

handleHdDown : function(e, t)
{
Ext.ux.lf.LockingTreeGridView.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));
}
}
},

onLoad : function(store, records, options)
{
var ridx;
if (
options &&
options.params &&
(
options.params[store.paramNames.active_node] === null ||
store.indexOfId(options.params[store.paramNames.active_node]) == -1
)
) {
Ext.ux.lf.LockingTreeGridView.superclass.onLoad.call(this, store, records, options);
}
},

onAdd : function(store, records, index)
{
Ext.ux.lf.LockingTreeGridView.superclass.onAdd.call(this, ds, records, index);
if (this.mainWrap) {
this.processRows(0);
}
},

onRemove : function(store, record, index, isUpdate)
{
Ext.ux.lf.LockingTreeGridView.superclass.onRemove.call(this, store, record, index, isUpdate);
if(isUpdate !== true){
if (this.mainWrap) {
this.processRows(0);
}
}
},

onUpdate : function(store, record)
{
Ext.ux.lf.LockingTreeGridView.superclass.onUpdate.call(this, store, record);
if (this.mainWrap) {
this.processRows(0);
}
},

onStoreExpandNode : function(store, record)
{
this.expandRow(record);
},

onStoreCollapseNode : function(store, record)
{
this.collapseRow(record);
},

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.getColumnWidth(0) + 'px';
},

getTotalWidth : function() {
return (this.cm.getTotalWidth() - this.cm.getColumnWidth(0)) + '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 : i == 0 ? true : false
};
}
return cs;
},

renderBody : function(){
var markup = this.renderRows() || ['&#160;', '&#160;'];
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(){

},

updateLockedWidth: function()
{
var lw = this.cm.getColumnWidth(0),
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.lf.LockingTreeGrid = Ext.extend(Ext.grid.GridPanel,
{

master_column_id : 0,
tg_cls : 'ux-maximgb-tg-panel',

initComponent : function()
{
this.initComponentPreOverride();
Ext.ux.lf.LockingTreeGrid.superclass.initComponent.call(this);
this.getSelectionModel().on('selectionchange', this.onTreeGridSelectionChange, this);
this.initComponentPostOverride();
},

initComponentPreOverride : Ext.emptyFn,

initComponentPostOverride : Ext.emptyFn,

onRender : function(ct, position)
{
Ext.ux.lf.LockingTreeGrid.superclass.onRender.call(this, ct, position);
this.el.addClass(this.tg_cls);
},

getView : function()
{
if (!this.view) {
this.view = new Ext.ux.lf.LockingTreeGridView(this.viewConfig);
}
return this.view;
},

onClick : function(e)
{
var target = e.getTarget(),
view = this.getView(),
row = view.findRowIndex(target),
store = this.getStore(),
sm = this.getSelectionModel(),
record, record_id, do_default = true;

if (row !== false) {
if (Ext.fly(target).hasClass('ux-maximgb-tg-elbow-active')) {
record = store.getAt(row);
if (store.isExpandedNode(record)) {
store.collapseNode(record);
}
else {
store.expandNode(record);
}
do_default = false;
}
}

if (do_default) {
Ext.ux.lf.LockingTreeGrid.superclass.onClick.call(this, e);
}
},

onMouseDown : function(e)
{
var target = e.getTarget();

if (!Ext.fly(target).hasClass('ux-maximgb-tg-elbow-active')) {
Ext.ux.lf.LockingTreeGrid.superclass.onMouseDown.call(this, e);
}
},

onTreeGridSelectionChange : function(sm, selection)
{
var record, ancestors, store = this.getStore();

if (sm.getSelected) {
record = sm.getSelected();
store.setActiveNode(record);
}

else if (sm.getSelectedCell && selection) {
record = selection.record;
store.setActiveNode(record);
}

if (record) {
if (!store.isVisibleNode(record)) {
ancestors = store.getNodeAncestors(record);
while (ancestors.length > 0) {
store.expandNode(ancestors.pop());
}
}
}
}

});

Ext.reg('Ext.ux.lf.LockingTreeGrid', Ext.ux.lf.LockingTreeGrid);


This is my code I am using to instatiant my component for a test.




Ext.onReady(function(){

// sample static data for the store
var data = [
{"company":"0. Johnson & Johnson","_id":1,"_parent":null,"_level":1,"_is_leaf":true},
{"company":"1. American International Group, Inc.","_id":2,"_parent":null,"_level":1,"_is_leaf":true},
{"company":"99. Boeing Co.","_id":3,"_parent":null,"_level":1,"_is_leaf":false}
];


// create the data store
var record = Ext.data.Record.create([
{name: 'company'},
{name: '_id', type: 'int'},
{name: '_parent', type: 'auto'},
{name: '_level', type: 'int'},
{name: '_is_leaf', type: 'bool'}
]);


var store = new Ext.ux.maximgb.tg.AdjacencyListStore({
autoLoad : true,
reader: new Ext.data.JsonReader({id: '_id'}, record),
proxy: new Ext.data.MemoryProxy(data)
});

console.log(store);

// create the Grid
// To use locking functionality we must explicitly specify the LockingColumnModel and the LockingGridView
var grid = new Ext.ux.lf.LockingTreeGrid({
store: store,
colModel: new Ext.grid.ColumnModel([
{header: 'Company', width: 160, sortable: true, dataIndex: 'company', id:'company'}
]),
stripeRows: true,
height: 350,
width: 500,
title: 'Locking Array Grid'
});


// render the grid to the specified div in the page
grid.render('grid-example');
});


Anyone?

lukefowell89
6 Dec 2010, 6:42 AM
I really need to figure this out quickly? Anyone got a sec to see if they can see any problems?

lukefowell89
8 Dec 2010, 1:15 AM
Anyone have any idea? really need some help, would appreciate it