app/assets/javascripts/ext_extensions/TreeGrid/src/GridView.js
Ext.ux.maximgb.tg.GridView = Ext.extend(Ext.grid.GridView,
{
expanded_icon_class : 'ux-maximgb-tg-elbow-minus',
last_expanded_icon_class : 'ux-maximgb-tg-elbow-end-minus',
collapsed_icon_class : 'ux-maximgb-tg-elbow-plus',
last_collapsed_icon_class : 'ux-maximgb-tg-elbow-end-plus',
skip_width_update_class: 'ux-maximgb-tg-skip-width-update',
// private - overriden
initTemplates : function()
{
var ts = this.templates || {};
if (!ts.row) {
ts.row = new Ext.Template(
'<div class="x-grid3-row ux-maximgb-tg-level-{level} {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.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}>{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}"> </div>',
'</div>'
);
}
if (!ts.elbow_line) {
ts.elbow_line = new Ext.Template(
'<div style="left: {left}px" class="{cls}"> </div>'
);
}
this.templates = ts;
Ext.ux.maximgb.tg.GridView.superclass.initTemplates.call(this);
},
// Private - Overriden
doRender : function(cs, rs, ds, startRow, colCount, stripe)
{
var ts = this.templates, ct = ts.cell, rt = ts.row, last = colCount-1;
var tstyle = 'width:'+this.getTotalWidth()+';';
// buffers
var buf = [], cb, c, p = {}, rp = {tstyle: tstyle}, r;
for (var j = 0, len = rs.length; j < len; j++) {
r = rs[j]; cb = [];
var rowIndex = (j+startRow);
var row_render_res = this.renderRow(r, rowIndex, colCount, ds, this.cm.getTotalWidth());
if (row_render_res === false) {
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 ' : '');
p.attr = p.cellAttr = "";
p.value = c.renderer.call(c.scope, 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 && typeof r.modified[c.name] !== 'undefined'){
p.css += ' x-grid3-dirty-cell';
}
// ----- Modification start
if (c.id == this.grid.master_column_id) {
p.treeui = this.renderCellTreeUI(r, ds);
ct = ts.mastercell;
}
else {
ct = ts.cell;
}
// ----- End of modification
cb[cb.length] = ct.apply(p);
}
}
else {
cb.push(row_render_res);
}
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("");
// ----- Modification start
if (!ds.isVisibleNode(r)) {
rp.display_style = 'display: none;';
}
else {
rp.display_style = '';
}
rp.level = ds.getNodeDepth(r);
// ----- End of modification
buf[buf.length] = rt.apply(rp);
}
return buf.join("");
},
renderCellTreeUI : function(record, store)
{
var tpl = this.templates.treeui,
line_tpl = this.templates.elbow_line,
tpl_data = {},
rec, parent,
depth = level = store.getNodeDepth(record);
tpl_data.wrap_width = (depth + 1) * 16;
if (level > 0) {
tpl_data.elbow_line = '';
rec = record;
left = 0;
while(level--) {
parent = store.getNodeParent(rec);
if (parent) {
if (store.hasNextSiblingNode(parent)) {
tpl_data.elbow_line =
line_tpl.apply({
left : level * 16,
cls : 'ux-maximgb-tg-elbow-line'
}) +
tpl_data.elbow_line;
}
else {
tpl_data.elbow_line =
line_tpl.apply({
left : level * 16,
cls : 'ux-maximgb-tg-elbow-empty'
}) +
tpl_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)) {
tpl_data.cls = 'ux-maximgb-tg-elbow';
}
else {
tpl_data.cls = 'ux-maximgb-tg-elbow-end';
}
}
else {
tpl_data.cls = 'ux-maximgb-tg-elbow-active ';
if (store.isExpandedNode(record)) {
if (store.hasNextSiblingNode(record)) {
tpl_data.cls += this.expanded_icon_class;
}
else {
tpl_data.cls += this.last_expanded_icon_class;
}
}
else {
if (store.hasNextSiblingNode(record)) {
tpl_data.cls += this.collapsed_icon_class;
}
else {
tpl_data.cls += this.last_collapsed_icon_class;
}
}
}
tpl_data.left = 1 + depth * 16;
return tpl.apply(tpl_data);
},
// Template method
renderRow : function(record, index, col_count, ds, total_width)
{
return false;
},
// private - overriden
afterRender : function()
{
Ext.ux.maximgb.tg.GridView.superclass.afterRender.call(this);
this.updateAllColumnWidths();
},
// private - overriden to support missing column td's case, if row is rendered by renderRow()
// method.
updateAllColumnWidths : function()
{
var tw = this.getTotalWidth(),
clen = this.cm.getColumnCount(),
ws = [],
len,
i;
for(i = 0; i < clen; i++){
ws[i] = this.getColumnWidth(i);
}
this.innerHd.firstChild.style.width = this.getOffsetWidth();
this.innerHd.firstChild.firstChild.style.width = tw;
this.mainBody.dom.style.width = tw;
for(i = 0; i < clen; i++){
var hd = this.getHeaderCell(i);
hd.style.width = ws[i];
}
var ns = this.getRows(), row, trow;
for(i = 0, len = ns.length; i < len; i++){
row = ns[i];
row.style.width = tw;
if(row.firstChild){
row.firstChild.style.width = tw;
trow = row.firstChild.rows[0];
for (var j = 0; j < clen && j < trow.childNodes.length; j++) {
if (!Ext.fly(trow.childNodes[j]).hasClass(this.skip_width_update_class)) {
trow.childNodes[j].style.width = ws[j];
}
}
}
}
this.onAllColumnWidthsUpdated(ws, tw);
},
// private - overriden to support missing column td's case, if row is rendered by renderRow()
// method.
updateColumnWidth : function(col, width)
{
var w = this.getColumnWidth(col);
var tw = this.getTotalWidth();
this.innerHd.firstChild.style.width = this.getOffsetWidth();
this.innerHd.firstChild.firstChild.style.width = tw;
this.mainBody.dom.style.width = tw;
var hd = this.getHeaderCell(col);
hd.style.width = w;
var ns = this.getRows(), row;
for(var i = 0, len = ns.length; i < len; i++){
row = ns[i];
row.style.width = tw;
if(row.firstChild){
row.firstChild.style.width = tw;
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 = w;
}
}
}
}
this.onColumnWidthUpdated(col, w, tw);
},
// private - overriden to support missing column td's case, if row is rendered by renderRow()
// method.
updateColumnHidden : function(col, hidden)
{
var tw = this.getTotalWidth();
this.innerHd.firstChild.style.width = this.getOffsetWidth();
this.innerHd.firstChild.firstChild.style.width = tw;
this.mainBody.dom.style.width = tw;
var display = hidden ? 'none' : '';
var hd = this.getHeaderCell(col);
hd.style.display = display;
var ns = this.getRows(), row, cell;
for(var i = 0, len = ns.length; i < len; i++){
row = ns[i];
row.style.width = tw;
if(row.firstChild){
row.firstChild.style.width = tw;
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, tw);
delete this.lastViewWidth; // force recalc
this.layout();
},
// private - overriden to skip hidden rows processing.
processRows : function(startRow, skipStripe)
{
var processed_cnt = 0;
if(this.ds.getCount() < 1){
return;
}
skipStripe = !this.grid.stripeRows; //skipStripe || !this.grid.stripeRows;
startRow = startRow || 0;
var rows = this.getRows();
var processed_cnt = 0;
Ext.each(rows, function(row, idx){
row.rowIndex = idx;
row.className = row.className.replace(this.rowClsRe, ' ');
if (row.style.display != 'none') {
if (!skipStripe && ((processed_cnt + 1) % 2 === 0)) {
row.className += ' x-grid3-row-alt';
}
processed_cnt++;
}
}, this);
Ext.fly(rows[0]).addClass(this.firstRowCls);
Ext.fly(rows[rows.length - 1]).addClass(this.lastRowCls);
},
ensureVisible : function(row, col, hscroll)
{
var ancestors, record = this.ds.getAt(row);
if (!this.ds.isVisibleNode(record)) {
ancestors = this.ds.getNodeAncestors(record);
while (ancestors.length > 0) {
record = ancestors.shift();
if (!this.ds.isExpandedNode(record)) {
this.ds.expandNode(record);
}
}
}
return Ext.ux.maximgb.tg.GridView.superclass.ensureVisible.call(this, row, col, hscroll);
},
// Private
expandRow : function(record, skip_process)
{
var ds = this.ds,
i, len, row, pmel, children, 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) {
if (ds.hasNextSiblingNode(record)) {
pmel.removeClass(this.collapsed_icon_class);
pmel.removeClass(this.last_collapsed_icon_class);
pmel.addClass(this.expanded_icon_class);
}
else {
pmel.removeClass(this.collapsed_icon_class);
pmel.removeClass(this.last_collapsed_icon_class);
pmel.addClass(this.last_expanded_icon_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) {
if (ds.hasNextSiblingNode(record)) {
pmel.removeClass(this.expanded_icon_class);
pmel.removeClass(this.last_expanded_icon_class);
pmel.addClass(this.collapsed_icon_class);
}
else {
pmel.removeClass(this.expanded_icon_class);
pmel.removeClass(this.last_expanded_icon_class);
pmel.addClass(this.last_collapsed_icon_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);
}
//this.updateAllColumnWidths();
},
/**
* @access private
*/
initData : function(ds, cm)
{
Ext.ux.maximgb.tg.GridView.superclass.initData.call(this, ds, cm);
if (this.ds) {
this.ds.un('expandnode', this.onStoreExpandNode, this);
this.ds.un('collapsenode', this.onStoreCollapseNode, this);
}
if (ds) {
ds.on('expandnode', this.onStoreExpandNode, this);
ds.on('collapsenode', this.onStoreCollapseNode, this);
}
},
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.maximgb.tg.GridView.superclass.onLoad.call(this, store, records, options);
}
},
onAdd : function(ds, records, index)
{
Ext.ux.maximgb.tg.GridView.superclass.onAdd.call(this, ds, records, index);
if (this.mainWrap) {
//this.updateAllColumnWidths();
this.processRows(0);
}
},
onRemove : function(ds, record, index, isUpdate)
{
Ext.ux.maximgb.tg.GridView.superclass.onRemove.call(this, ds, record, index, isUpdate);
if(isUpdate !== true){
if (this.mainWrap) {
//this.updateAllColumnWidths();
this.processRows(0);
}
}
},
onUpdate : function(ds, record)
{
Ext.ux.maximgb.tg.GridView.superclass.onUpdate.call(this, ds, record);
if (this.mainWrap) {
//this.updateAllColumnWidths();
this.processRows(0);
}
},
onStoreExpandNode : function(store, rc)
{
this.expandRow(rc);
},
onStoreCollapseNode : function(store, rc)
{
this.collapseRow(rc);
}
});