You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

271 lines
8.7 KiB

/*
================================================================================
GroupTree
================================================================================
*/
/**
* GroupTree constructor.
*
* @param kwArgs.id [String] DOM node id
* @param kwArgs.icns [String] URL to magnifying glass icon
* @param kwArgs.minIcon [String] URL to min.gif
* @param kwArgs.plusIcon [String] URL to plus.gif
*/
bobj.crv.newGroupTree = function(kwArgs) {
var UPDATE = MochiKit.Base.update;
kwArgs = UPDATE ( {
id : bobj.uniqueId (),
visualStyle : {
className : null,
backgroundColor : null,
borderWidth : null,
borderStyle : null,
borderColor : null,
fontFamily : null,
fontWeight : null,
textDecoration : null,
color : null,
width : null,
height : null,
fontStyle : null,
fontSize : null
},
icns : bobj.crvUri ('images/magnify.gif'),
minIcon : bobj.crvUri ('images/min.gif'),
plusIcon : bobj.crvUri ('images/plus.gif')
}, kwArgs);
var o = newTreeWidget (kwArgs.id + '_tree', '100%', '100%', kwArgs.icns, null, null, 'groupTree',
bobj.crv.GroupTree._expand, bobj.crv.GroupTree._collapse, null, kwArgs.minIcon, kwArgs.plusIcon);
o._children = [];
o._modalChildren = [];
o._lastNodeIdInitialized = -1;
o._lastNodeInitialized = null;
o._curSigs = [];
bobj.fillIn (o, kwArgs);
o.widgetType = 'GroupTree';
o.initOld = o.init;
UPDATE (o, bobj.crv.GroupTree);
return o;
};
bobj.crv.GroupTree = {
/**
* Disposes group tree
*/
dispose : function() {
/* removes all the signals */
while (this._curSigs.length > 0) {
bobj.crv.SignalDisposer.dispose (this._curSigs.pop ());
}
/* disposes all the children*/
while (this._children.length > 0) {
var child = this._children.pop ();
child.dispose ();
bobj.deleteWidget (child);
delete child;
}
this._lastNodeIdInitialized = -1;
this._lastNodeInitialized = null;
this.sub = [];
bobj.removeAllChildElements(this.treeLyr);
},
getModalChildren : function () {
return this._modalChildren;
},
/**
* Adds a child widget as a group tree node.
*
* @param widget
* [Widget] Child tree node widget
*/
addChild : function(widget) {
var Base = MochiKit.Base;
var Signal = MochiKit.Signal;
var connect = Signal.connect;
widget.expandPath = this._children.length + '';
this._children.push (widget);
widget._updateProperty (this.enableDrilldown, this.enableNavigation);
this.add (widget);
widget.delayedAddChild (this.enableDrilldown, this.enableNavigation);
this._curSigs.push (connect (widget, 'grpDrilldown', Base.partial (Signal.signal, this, 'grpDrilldown')));
this._curSigs.push (connect (widget, 'grpNodeRetrieveChildren', Base.partial (Signal.signal, this, 'grpNodeRetrieveChildren')));
},
/**
* Since GroupTree nodes are delay loaded, we would have to store the timeout ids to cancel them in case user drill down to another views
*/
delayedBatchAdd : function(children) {
if (!children || children.length == 0)
return;
this._modalChildren = children;
var childrenHTML = "";
var numChildrenToRender = children.length > 100 ? 100 : children.length;
if(numChildrenToRender > 0) {
for(var i = 0 ; i < numChildrenToRender ; i++) {
var child = bobj.crv.createWidget (this._modalChildren[i]);
this.addChild(child);
if(this.initialized())
childrenHTML += child.getHTML(0);
}
}
if(this.initialized()) {
this.appendChildrenHTML (childrenHTML);
this.initChildren ();
}
},
appendChildrenHTML : function (childrenHTML) {
append (this.treeLyr, childrenHTML);
},
init : function() {
this.initOld ();
bobj.setVisualStyle (this.layer, this.visualStyle);
this.css.verticalAlign = "top";
this.initChildren ();
this._groupTreeListener = new bobj.crv.GroupTreeListener(this);
},
update : function(update) {
if (update.cons == "bobj.crv.newGroupTree") {
var args = update.args;
var path = args.lastExpandedPath;
/* if path specified, then update specific path, otherwise recreate grouptree */
// if user has expands a node after session timeout -> the whole gt must be rerendered
if (path.length > 0 && this._children.length > 0) {
this.updateNode (path, update);
} else {
this.refreshChildNodes (update)
}
}
},
delayedAddChild : function(widget) {
this.addChild (widget);
append (this.treeLyr, widget.getHTML (this.initialIndent));
},
initChildren : function () {
while(this._lastNodeIdInitialized < this._children.length - 1)
this.initNextChild ();
},
initNextChild : function () {
var nextNode = null;
var nextNodeId = -1;
if(this._lastNodeIdInitialized == -1) {
var treeSpanLayer = getLayer("treeCont_" + this.id);
nextNode = treeSpanLayer.firstChild;
nextNodeId = 0;
}
else {
nextNode = this._lastNodeInitialized.nextSibling;
while(!(nextNode.id && nextNode.id.indexOf("TWe_") > -1))
nextNode = nextNode.nextSibling;
nextNodeId = this._lastNodeIdInitialized + 1;
}
if(nextNodeId < this._children.length && nextNode != null) {
this._children[nextNodeId].init(nextNode);
this._lastNodeInitialized = nextNode;
this._lastNodeIdInitialized = nextNodeId;
}
},
getBestFitHeight : function () {
return bobj.getHiddenElementDimensions (this.layer).h;
/**
* Since container of tree could be invisible, getHiddenElementDimensions has to be called
* instead of element.getHeight()
*/
},
/**
* refreshes group tree by removing all nodes and adding new ones
*/
refreshChildNodes : function(update) {
this.dispose ();
this.delayedBatchAdd (update.children);
MochiKit.Signal.signal(this, "refreshed");
},
/**
* @param path
* path to the node that should be updated eg) 0-1-2
* @param newTree
* the new tree sent in update
*
* Updates children of node specified by path
*/
updateNode : function(path, newTree) {
if (path && path.length > 0) {
var pathArray = path.split ('-');
var node = this;
var newNode = newTree;
/* Navigating to the node that requires update */
for ( var i = 0, len = pathArray.length; i < len; i++) {
if (node && newNode) {
var childIndex = parseInt (pathArray[i]);
newNode = newNode.children[childIndex];
node = node._children[childIndex];
} else {
break;
}
}
/* if we found the node that requires update, then update its children */
if (node && newNode && newNode.args.groupPath == node.groupPath && node._children.length == 0) {
for ( var nodeNum in newNode.children) {
var newChildnode = bobj.crv.createWidget (newNode.children[nodeNum]);
node.addChild (newChildnode);
}
node.delayedAddChild (this.enableDrilldown, this.enableNavigation);
node.expand ();
}
}
},
getChildrenCount : function () {
return this.sub.length;
},
/**
* Private. Callback function when a (complete) group tree node is collapsed.
*/
_collapse : function(expandPath) {
MochiKit.Signal.signal (this, 'grpNodeCollapse', expandPath);
},
/**
* Private. Callback function when a (complete) group tree node is expanded.
*/
_expand : function(expandPath) {
MochiKit.Signal.signal (this, 'grpNodeExpand', expandPath);
},
resize : function(width, height) {
bobj.setOuterSize (this.layer, width, height);
MochiKit.Signal.signal(this, "resized");
}
};