/*
*+------------------------------------------------------------------------+
*| Licensed Materials - Property of IBM
*| BI and PM: prmt
*| (C) Copyright IBM Corp. 2002, 2020
*|
*| US Government Users Restricted Rights - Use, duplication or
*| disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
*|
*+------------------------------------------------------------------------+
*/
//TREE CONTROL
// oPane: the HTML element where the tree will be rendered
// oSubmit: the form control to submit selections to the server
// bRequired: is this a required field [true|false]
// bMultiSelect: can the user pick more than one value [true|false]
// sRef: the name of this object
// oImgTest: the image object used for validation handling
// oErrorFeedback: object used to provide validation feedback
// sCVId
// sStyle
// sTextDir
// sPromptName: the name of the prompt associated with the tree. This is used as a cache key prefix
CInnerTree.prototype = new CTree;
function CInnerTree(oPane, oSubmit, bRequired, bMultiSelect, sRef, oImgTest, oErrorFeedback, sCVId, sStyle, sTextDir, sPromptName, oPromptControl)
{
this.setCVId(sCVId);
this.m_style = sStyle;
this.m_sTextDir = sTextDir;
//html div element where adornments will be rendered
this.m_oOuterPane = oPane;
//html element where the tree will be rendered
this.m_oPane = null;
var v_sCustomDir = cssParser( sStyle, "direction", true );
var v_sFinalDir = ((v_sCustomDir == "ltr" || v_sCustomDir == "rtl") ? v_sCustomDir : PRMT_BidiUtils.lookupDirection(oPane));
this.m_sDirection = ( v_sFinalDir == "rtl" ? "RTL" : "");
//create a root node for the tree
//new nodes are added by calling the appendChild method for each node
this.m_oRoot = new CInnerTreeNode(null, tntRoot, true, 'root', 'root', false);
this.m_oRoot.m_oTree = this;
this.m_oRoot.setTreeRef(K_PRMT_sEMPTY);
this.m_oSubmit = oSubmit;
this.m_bRequired = bRequired;
//determine the selection mode for the tree
if (bMultiSelect == false)
{
this.m_iSelectionMode = SINGLE_TREE_SELECTION;
this.m_sSelectTreeUI = NORMAL_TREE;
}
else
{
this.m_iSelectionMode = DISCONTIGUOUS_TREE_SELECTION;
this.m_sSelectTreeUI = CHECKBOX_TREE;
}
//check the state of the control?
//this needs to happen after the nodes are added
this.m_bValid = false;
this.m_sRef = sRef;
//maintain a list of selections
this.m_sTreeProcessResult = K_PRMT_sEMPTY;
this.m_oErrorFeedback = oErrorFeedback;
//../prompting/images for handling errors
this.m_oImgCheck = oImgTest;
if (this.m_oImgCheck != null)
{
this.m_oImgErrorFalse= new Image();
this.m_oImgErrorFalse.src = ERROR_TIMED_SMALL_OFF;
this.m_oImgErrorTrue = new Image();
this.m_oImgErrorTrue.src = ERROR_TIMED_SMALL;
}
this.m_bShowRootNode = false;
this.m_bLoadOnTheFly = false;
this.m_iIsLoading = 0;
this.m_bForceSelectionAtLowestLevel = false;
this.m_bAllowSelectionToggle = true;
this.m_oAnchorNode = null;
this.m_bAllowDragDrop = false;
this.m_fOnDragStartFunc = null;
this.m_fOnDragFunc = null;
this.m_fOnDragEndFunc = null;
this.m_fOnContextMenu = null;
this.m_bTrackSelectionOrder = false;
this.m_aSelectionOrder = [];
this.m_fSingleClickFunc = null;
this.m_fDoubleClickFunc = null;
this.m_bHideAdornments = false;
this.m_bMustChangeDefault = false;
this.m_bHideOuterTable = false;
this.m_bRecursiveSelect = true;
this.m_bPromptTree = false;
this.m_iMaxValueCount = 5000;
this.m_bShowPreviousValues = true;
this.m_aAllSelections = null;
this.m_iContainerWidth = null;
this.m_iContainerHeight = null;
this.m_bNodesCanHaveChildren = true;
this.m_bIsDisabled = false;
this.m_bHasBeenDrawn = false;
this.m_oLastSelectedNode = null;
//skin folder
this.m_sSkin = (typeof getPromptSkin != K_PRMT_sUNDEFINED ? getPromptSkin() : K_PRMT_sDEFAULTSKIN);
if (typeof gDispatcher != K_PRMT_sUNDEFINED) // Try to find global dispatcher object first
{
this.m_oDispatcher = gDispatcher;
}
else if (typeof CDispatcher != K_PRMT_sUNDEFINED)
{
this.m_oDispatcher = new CDispatcher();
}
else
{
this.m_oDispatcher = null;
}
this.m_sServerPath = this.getGateway();
// DOM objects used to create child nodes.
this.m_oTREELINE = document.createElement("IMG");
this.m_oTREELINE.src = PROMT_IMAGES + "blank.gif";
this.m_oTREELINE.alt = "";
this.m_oTREELINE.className = "clsTreeLineIcon";
this.m_oTREELINE.align = gsCTREE_middle;
this.m_oTREELINE.setAttribute(gsCTREE_treeRef, gsCTREE_img);
this.m_oDIVnewElement = document.createElement("DIV");
this.m_oDIVGroupElement = document.createElement("DIV");
this.m_oDIVGroupElement.setAttribute(K_PRMT_ARIA_ROLE,K_PRMT_TREE_ROLE_GROUP);
this.m_oNOBR = document.createElement("NOBR");
this.m_oNOBR.setAttribute(gsCTREE_treeRef, gsCTREE_nobr);
this.m_oIcon = document.createElement("IMG");
this.m_oIcon.setAttribute(gsCTREE_treeRef, gsCTREE_img);
this.m_oIndicatorSPAN = document.createElement("SPAN");
this.m_oIndicatorSPAN.style.paddingLeft = 3;
this.m_oIndicatorIMG = document.createElement("IMG");
this.m_oIndicatorIMG.align = gsCTREE_middle;
this.m_oTextSPAN = document.createElement("SPAN");
this.m_oToggleIMG = document.createElement("IMG");
this.m_oToggleIMG.align = gsCTREE_middle;
this.m_oToggleIMG.onclick = null;
this.m_oToggleIMG.src = (this.m_sDirection == "RTL" ? TREE_L_ONLY_RTL : TREE_L_ONLY);
this.m_oCheckIMG = document.createElement("IMG");
this.m_oCheckIMG.align = gsCTREE_middle;
/*RTC 364636: BUG: [WA][IE11] Tree Checkbox checkmarks do not update correctly*/
var isIE11 = !!navigator.userAgent.match(/Trident.*rv\:11\./);
this.m_oCheckDIV = isIE11? createCheckBoxTable() : document.createElement("DIV");
var checkBoxInputParent = isIE11? this.m_oCheckDIV.getElementsByTagName('div')[0] : this.m_oCheckDIV;
var v_oCheckInput = document.createElement("INPUT");
v_oCheckInput.type = "checkbox";
v_oCheckInput.tabIndex = -1;
v_oCheckInput.className = "dijitCheckBoxInput";
checkBoxInputParent.appendChild(v_oCheckInput);
this.m_oLabelSPAN = document.createElement("SPAN");
this.m_oAncestry = null;
if (sPromptName)
{
this.setAllowStateCache(SYSTEMPROPERTY_TREE_CACHE_ENABLED, sPromptName);
}
if (oPromptControl)
{
this.savePromptControlRef(oPromptControl);
}
}
function createCheckBoxTable()
{
var table = document.createElement("table");
var tr = document.createElement("tr");
var td = document.createElement("td");
var div = document.createElement("div");
td.appendChild(div);
tr.appendChild(td);
table.appendChild(tr);
return table;
};
// * CInnerTree.prototype = new CPromptControl();
// Set this to the tree's parameter name if this is a prompt control tree
// getPromptValues OM function will be called automatically if this is a prompting tree
CInnerTree.prototype.redrawNodeToggle = function(node, nodeId)
{
var newToggleIcon = document.getElementById(nodeId + gsCTREE_toggle + node.getTreeHierarchy());
if (newToggleIcon != null)
{
this.detailToogleIcon(node, newToggleIcon);
}
};
CInnerTree.prototype.drawLoading = function(node, nodeId)
{
var theElement = document.getElementById(nodeId);
if (!theElement && node.getNodeType() == TREE_ROOT && this.getRootNodeShowing() == false)
{
theElement = this.m_oPane;
}
if (theElement != null)
{
var newDivContainer = document.createElement("DIV");
newDivContainer.className = CLS_TREE_LEVEL;
newDivContainer.id = this.getName() + node.getTreeRef() + "loading";
newDivContainer.style.width = "100%";
var newNobrContainer = document.createElement("NOBR");
this.drawTreeLines(node, newNobrContainer, node.getLevel() + 1);
if (!(node.getNodeType() == TREE_ROOT && node.getTree().getRootNodeShowing() == false && node.getMoreData() != true))
{
var newLIcon = document.createElement("IMG");
newLIcon.align = gsCTREE_middle;
newLIcon.src = (this.m_sDirection == "RTL" ? TREE_L_ONLY_RTL : TREE_L_ONLY);
newNobrContainer.appendChild(newLIcon);
}
var newStateIcon = document.createElement("IMG");
newStateIcon.align = gsCTREE_middle;
newStateIcon.src = TREE_LOADING;
newNobrContainer.appendChild(newStateIcon);
var newLabelContainer = document.createElement("SPAN");
newLabelContainer.className = CLS_TREE_NODE_UNSELECTED + K_PRMT_sSP + CLS_TREE_TEXT;
//We need the localized string for "Loading..." here
if (typeof PMT_TRE_TREE_LOADING != K_PRMT_sUNDEFINED)
{
var newStateText = document.createTextNode(PMT_TRE_TREE_LOADING);
newLabelContainer.appendChild(newStateText);
newLabelContainer.title = PMT_TRE_TREE_LOADING;
}
newNobrContainer.appendChild(newLabelContainer);
newDivContainer.appendChild(newNobrContainer);
theElement.appendChild(newDivContainer);
}
};
CInnerTree.prototype.drawMoreData = function(node, nodeId)
{
var theElement = document.getElementById(nodeId);
if (!theElement && node.getNodeType() == TREE_ROOT && this.getRootNodeShowing() == false)
{
theElement = this.m_oPane;
}
var childrenContainer = (theElement.getAttribute("role") == "tree"? theElement : theElement.firstChild.nextSibling);
if (theElement != null && childrenContainer != null && (childrenContainer.getAttribute("role") == "group" || childrenContainer.getAttribute("role") == "tree"))
{
var newDivContainer = document.createElement("DIV");
newDivContainer.className = CLS_TREE_LEVEL;
newDivContainer.id = this.getName() + node.getTreeRef() + "moredata";
newDivContainer.style.width = "100%";
var newNobrContainer = document.createElement("NOBR");
this.drawTreeLines(node, newNobrContainer, node.getLevel() + 1);
var newLIcon = document.createElement("IMG");
newLIcon.align = gsCTREE_middle;
newLIcon.src = (this.m_sDirection == "RTL" ? TREE_L_ONLY_RTL : TREE_L_ONLY);
newNobrContainer.appendChild(newLIcon);
var newStateIcon = document.createElement("IMG");
newStateIcon.align = gsCTREE_middle;
newStateIcon.src = TREE_MORE_DATA;
newNobrContainer.appendChild(newStateIcon);
var newLabelContainer = document.createElement("SPAN");
newLabelContainer.className = CLS_TREE_NODE_UNSELECTED + K_PRMT_sSP + CLS_TREE_TEXT_LINK;
//We need the localized string for "More" here
if (typeof PMT_TRE_MORE != K_PRMT_sUNDEFINED)
{
var newStateText = document.createTextNode(PMT_TRE_MORE);
newLabelContainer.appendChild(newStateText);
newLabelContainer.title = PMT_TRE_MORE;
}
newLabelContainer.id = this.getName() + node.getTreeRef() + "moredatalabel";
newLabelContainer.setAttribute(gsCTREE_tree, this.getName());
newLabelContainer.setAttribute(gsCTREE_treeRef, node.getTreeRef());
newLabelContainer.tabIndex = 0;
PRMTUtils.f_addEvent(newLabelContainer, "click", getMoreDataForTreeNode);
PRMTUtils.f_addEvent(newLabelContainer, "keydown", getMoreDataForTreeNode);
PRMTUtils.f_addEvent(newLabelContainer, "keypress", getMoreDataForTreeNode);
newNobrContainer.appendChild(newLabelContainer);
newDivContainer.appendChild(newNobrContainer);
childrenContainer.appendChild(newDivContainer);
}
};
CInnerTree.prototype.drawTreeLines = function(node, newElement, drawToLevel)
{
// put in appropriate spacers
if (drawToLevel > 1)
{
for (var n = 1; n < drawToLevel; n++)
{
var spacerIcon = this.m_oTREELINE.cloneNode(true);
var oParent = node.getParentAtLevel(n);
if (oParent.isLastSibling() == true && oParent.getParent().getMoreData() != true)
{
//if the parent was last
spacerIcon.className = spacerIcon.className + " clsTreeLineIconSpace";
}
newElement.appendChild(spacerIcon);
}
}
};
CInnerTree.prototype.drawOuterTable = function()
{
if (this.m_oOuterPane != null)
{
var sId = this.m_sRef;
var sStyle = this.getStyle();
var HTMLOut = "
";
this.m_oOuterPane.innerHTML = HTMLOut;
if (this.getErrorFeedbackWidget() == null) {
this.setErrorFeedbackWidget(document.getElementById("feedback_tree" + sId));
}
if (this.getImgCheck() == null)
{
this.setImgCheck(document.getElementById("imgTest_tree" + sId));
if (this.getImgCheck() != null)
{
this.setImgErrorFalse(ERROR_TIMED_SMALL_OFF);
this.setImgErrorTrue(ERROR_TIMED_SMALL);
}
}
}
};
CInnerTree.prototype.createElementIndicator = function(node, treeName, treeRef)
{
// create indicator span
var newElementIndicator = this.m_oIndicatorSPAN.cloneNode(true);
newElementIndicator.id = treeName + treeRef + gsCTREE_indicatorSpan;
newElementIndicator.setAttribute(gsCTREE_treeRef, treeRef);
newElementIndicator.setAttribute(gsCTREE_dragRef, treeRef.toString());
newElementIndicator.setAttribute(gsCTREE_dragTree, treeName);
newElementIndicator.setAttribute(gsCTREE_tree, treeName);
// create the indicator image
var newElementIndicatorImage = this.m_oIndicatorIMG.cloneNode(true);
newElementIndicatorImage.id = treeName + treeRef + gsCTREE_indicator;
newElementIndicatorImage.setAttribute(gsCTREE_treeRef, treeRef);
newElementIndicatorImage.setAttribute(gsCTREE_dragRef, treeRef.toString());
newElementIndicatorImage.setAttribute(gsCTREE_dragTree, treeName);
newElementIndicatorImage.setAttribute(gsCTREE_tree, treeName);
// set the image
newElementIndicatorImage.src = node.getIndicator();
// add this into the span
newElementIndicator.appendChild(newElementIndicatorImage);
return newElementIndicator;
};
CInnerTree.prototype.draw = function(node, oParentElement)
{
if (node.getTree().getDisabled() == true)
{
return false;
}
var treeRef = node.getTreeRef();
var treeName = this.getName();
//if the node is the root node, removes the old root node so that the entire tree is redrawn
//this takes care of the case where a loading tree is replaced with real data
if (node.getNodeType() == TREE_ROOT)
{
var rootNode = document.getElementById(treeName);
if (rootNode != null) {
oParentElement.removeChild(rootNode);
}
oParentElement.setAttribute(gsCTREE_treeRef, treeRef);
oParentElement.setAttribute(gsCTREE_tree, treeName);
}
// clone outer container DIV (it's much faster than create a new one)
var nodeElement = this.m_oDIVnewElement.cloneNode(true);
PRMTUtils.f_addEvent( nodeElement, "dragstart", dragStartOnNode );
PRMTUtils.f_addEvent( nodeElement, "drag", dragOnNode );
PRMTUtils.f_addEvent( nodeElement, "dragend", dragEndOnNode );
nodeElement.setAttribute(gsCTREE_treeRef, treeRef);
nodeElement.setAttribute(gsCTREE_tree, treeName);
if (treeRef == K_PRMT_sEMPTY) {
nodeElement.setAttribute(K_PRMT_ARIA_ROLE, K_PRMT_TREE_ROLE_TREE);
}
nodeElement.id = treeName + treeRef;
if (!(node.getNodeType() == TREE_ROOT && this.getRootNodeShowing() == false))
{
this.drawNode(node, nodeElement);
}
// ******************************************************************
// deal with children
// ******************************************************************
oParentElement.appendChild(nodeElement);
this.drawNodeChildren (node, nodeElement);
this.m_bHasBeenDrawn = true;
};
/**
* Draws the icon + / - that acts as a toogle for the branch
*
*/
CInnerTree.prototype.drawToogleIcon = function(node) {
var newToggleIcon = this.m_oToggleIMG.cloneNode(true);
newToggleIcon.src = PROMT_IMAGES + "blank.gif";
return this.detailToogleIcon(node, newToggleIcon);
};
CInnerTree.prototype.detailToogleIcon = function(node, newToggleIcon) {
// text for high contrast
var newToggleText = this.m_oTextSPAN.cloneNode(true);
newToggleText.className= K_PRMT_TREE_TOGGLE_TEXT;
newToggleText.setAttribute(K_PRMT_ARIA_ROLE, K_PRMT_ARIA_ROLE_PRESENTATION);
var toggleTextContent = "";
if (node.canHaveChildren() == true)
{
if (node.isOpen() == true)
{
newToggleIcon.className = K_PRMT_TREE_TOGGLE_OPENED + this.m_sDirection;
newToggleIcon.title = PMT_TRE_COLLAPSE;
newToggleIcon.alt = PMT_TRE_COLLAPSE;
toggleTextContent = "-";
}
else
{
newToggleIcon.className= K_PRMT_TREE_TOGGLE_CLOSED + this.m_sDirection;
newToggleIcon.title = PMT_TRE_EXPAND;
newToggleIcon.alt = PMT_TRE_EXPAND;
toggleTextContent = "+";
}
newToggleIcon.tabIndex = -1;
newToggleIcon.onclick = toggle;
newToggleText.onclick = toggle;
}
else
{
newToggleIcon.className= K_PRMT_TREE_TOGGLE_LEAF;
newToggleIcon.src = PROMT_IMAGES + "blank.gif";
newToggleIcon.alt = "";
newToggleIcon.onclick = null;
}
var toggleTextNode= document.createTextNode(toggleTextContent);
newToggleText.appendChild(toggleTextNode);
newToggleIcon.setAttribute(gsCTREE_treeRef, gsCTREE_img);
return [newToggleIcon, newToggleText];
};
/**
* Draws the checkbox
*
*/
CInnerTree.prototype.drawNodeCheckboxIcon = function(node) {
var newCheckBox = this.m_oCheckDIV.cloneNode(true);
updateCheckboxClass(newCheckBox, node);
newCheckBox.setAttribute(gsCTREE_treeRef, gsCTREE_checkbox);
//set up events
if ((node.getTree().getForceSelectionAtLowestLevel() == true && node.getNodeType() == TREE_ITEM) || (node.getTree().getForceSelectionAtLowestLevel() == false))
{
PRMTUtils.f_addEvent(newCheckBox.firstChild, "click", selectNode);
}
return newCheckBox;
};
/**
* Draws the label Node label
*
*/
CInnerTree.prototype.drawNodeLabel = function(node, treeName, treeRef) {
var nodeElementLabelContainer = this.m_oLabelSPAN.cloneNode(true);
nodeElementLabelContainer.id = treeName + treeRef + gsCTREE_labelText;
this.updateLabelClass(nodeElementLabelContainer, getClassName(node, this), node);
nodeElementLabelContainer.setAttribute(gsCTREE_treeRef, treeRef);
nodeElementLabelContainer.setAttribute(gsCTREE_dragRef, treeRef.toString());
nodeElementLabelContainer.setAttribute(gsCTREE_dragTree, treeName);
nodeElementLabelContainer.setAttribute(gsCTREE_tree, treeName);
nodeElementLabelContainer.setAttribute(K_PRMT_ARIA_ROLE, K_PRMT_TREE_ROLE_TREEITEM);
node.m_oLabelText = nodeElementLabelContainer;
if (node.isFirst()) {
nodeElementLabelContainer.tabIndex = 0;
this.m_lastFocus = nodeElementLabelContainer;
}
var labelText = document.createTextNode( G_IsBidiEnabled && this.m_sTextDir ? PRMT_BidiUtils.enforceBidiDirection(node.getName(), this.m_sTextDir) : node.getName() );
nodeElementLabelContainer.appendChild(labelText);
updateLabelAriaChecked(nodeElementLabelContainer, node);
var sStyle = this.getStyle();
nodeElementLabelContainer.style.color= cssParser(sStyle,"color",true);
nodeElementLabelContainer.style.backgroundColor= cssParser(sStyle,"background-color",true);
nodeElementLabelContainer.style.fontFamily= cssParser(sStyle,"font-family",true);
nodeElementLabelContainer.style.fontSize= cssParser(sStyle,"font-size",true);
nodeElementLabelContainer.style.fontWeight= cssParser(sStyle,"font-weight",true);
nodeElementLabelContainer.style.fontStyle= cssParser(sStyle,"font-style",true);
nodeElementLabelContainer.style.fontVariant= cssParser(sStyle,"font-variant",true);
nodeElementLabelContainer.style.textAlign= cssParser(sStyle,"text-align",true);
nodeElementLabelContainer.style.textVariant= cssParser(sStyle,"text-variant",true);
nodeElementLabelContainer.style.textIndent= cssParser(sStyle,"text-indent",true);
nodeElementLabelContainer.style.textTransform= cssParser(sStyle,"text-transform",true);
nodeElementLabelContainer.setAttribute(gsCTREE_treeRef, treeRef);
nodeElementLabelContainer.setAttribute(gsCTREE_dragRef, treeRef.toString());
nodeElementLabelContainer.setAttribute(gsCTREE_dragTree, treeName);
nodeElementLabelContainer.setAttribute(gsCTREE_tree, treeName);
nodeElementLabelContainer.setAttribute("onfocus","this.classname='" + CLS_TREE_NODE_HOVER + " " + CLS_TREE_TEXT + "';");
nodeElementLabelContainer.setAttribute("onblur","this.classname='" + CLS_TREE_NODE_UNSELECTED + " " + CLS_TREE_TEXT + "';");
return nodeElementLabelContainer;
};
/**
* Node structure
*
*
*
* [ checkbox ]
*
* [ indicator ]
*
*
*
*
*
*/
CInnerTree.prototype.drawNode = function(node, nodeElement) {
var treeRef = node.getTreeRef();
var treeName = this.getName();
nodeElement.className = CLS_TREE_LEVEL;
nodeElement.setAttribute(gsCTREE_dragRef, treeRef.toString());
nodeElement.setAttribute(gsCTREE_dragTree, treeName);
nodeElement.setAttribute(K_PRMT_ARIA_ROLE, K_PRMT_ARIA_ROLE_PRESENTATION);
//
var newNobr = this.m_oNOBR.cloneNode(true);
//var newNobr = this.m_oDIVnewElement.cloneNode(true);
newNobr.setAttribute(gsCTREE_treeRef, gsCTREE_nobr);
newNobr.setAttribute(gsCTREE_tree, treeName);
newNobr.setAttribute(K_PRMT_ARIA_ROLE, K_PRMT_ARIA_ROLE_PRESENTATION);
newNobr.setAttribute("style", "white-space: nowrap;");
nodeElement.appendChild(newNobr);
this.drawTreeLines(node, newNobr, node.getLevel());
// add [ indicator :
]
var nodeElementIndicator = null;
if (node.getIndicator() != null)
{
nodeElementIndicator = createElementIndicator(node,treeName,treeRef);
}
// create
var nodeElementText = this.m_oTextSPAN.cloneNode(true);
nodeElementText.id = treeName + treeRef + gsCTREE_label;
nodeElementText.setAttribute(gsCTREE_treeRef, treeRef);
nodeElementText.setAttribute(gsCTREE_dragRef, treeRef.toString());
nodeElementText.setAttribute(gsCTREE_dragTree, treeName);
nodeElementText.setAttribute(gsCTREE_tree, treeName);
nodeElementText.setAttribute(K_PRMT_ARIA_ROLE, K_PRMT_ARIA_ROLE_PRESENTATION);
nodeElementText.title = (node.getTooltip() != false? node.getTooltip() : node.getName());
if (G_IsBidiEnabled && this.m_sTextDir)
{
nodeElementText.title = PRMT_BidiUtils.enforceBidiDirection(nodeElementText.title, this.m_sTextDir);
}
// create node icon ->
var nodeElementIcon = this.m_oIcon.cloneNode(true);
nodeElementIcon.id = treeName + treeRef + gsCTREE_icon;
nodeElementIcon.setAttribute(gsCTREE_dragRef, treeRef.toString());
nodeElementIcon.setAttribute(gsCTREE_dragTree, treeName);
nodeElementIcon.setAttribute(K_PRMT_ARIA_ROLE, K_PRMT_ARIA_ROLE_PRESENTATION);
nodeElementIcon.src = PROMT_IMAGES + "blank.gif"; //getIconSrc(node);
nodeElementIcon.className = "clsTreeNodeIcon";
nodeElementIcon.alt = "";
nodeElementIcon.align = gsCTREE_middle;
var newToggleIcon = null;
if (node.getNodeType() == TREE_ROOT) {
nodeElementText.onclick = function() {return false;};
}
else
{
var newToggleElems = this.drawToogleIcon(node);
newToggleIcon = newToggleElems[0];
newToggleIcon.id = treeName + treeRef + gsCTREE_toggle + node.getTreeHierarchy();
newNobr.appendChild(newToggleIcon);
newNobr.appendChild(newToggleElems[1]);
if ((node.getTree().getForceSelectionAtLowestLevel() == true && node.getNodeType() == TREE_ITEM) || (node.getTree().getForceSelectionAtLowestLevel() == false))
{
nodeElementText.tabIndex = -1;
PRMTUtils.f_addEvent(nodeElementText, "click", selectNode.bind(this));
if (node.getTree().getSingleClickFunc() != null)
{
PRMTUtils.f_addEvent( nodeElementText, "click", singleClickCaller );
}
if (node.getTree().getDoubleClickFunc() != null)
{
PRMTUtils.f_addEvent( nodeElementText, "dblclick", doubleClickCaller );
}
nodeElementText.onmouseover = treeNodeMouseOver;
nodeElementText.onmouseout = treeNodeMouseOut;
PRMTUtils.f_addEvent( nodeElementText, "contextmenu", contextMenuCaller );
}
//add a checkbox for multiselect trees
if (this.getSelectionMode() != SINGLE_TREE_SELECTION && this.getSelectTreeUI() == CHECKBOX_TREE)
{
var newCheckBoxIcon = this.drawNodeCheckboxIcon(node);
newCheckBoxIcon.id = treeName + treeRef + gsCTREE_checkbox;
newCheckBoxIcon.firstChild.id = treeName + treeRef + gsCTREE_checkbox + "Input";
newNobr.appendChild(newCheckBoxIcon);
}
}
// add icon
nodeElementText.appendChild(nodeElementIcon);
// add the indicator if there is one
if (nodeElementIndicator != null)
{
nodeElementText.appendChild(nodeElementIndicator);
}
// aria-expanded attribute
*/
CInnerTree.prototype.updateAriaLabelContainer = function(oNode, sTreeName, ariaExpanded)
{
var labelContainer = document.getElementById(sTreeName + oNode.getTreeRef() + gsCTREE_labelText);
if (labelContainer)
{
labelContainer.setAttribute(K_PRMT_TREE_STATE_EXPANDED, ariaExpanded);
}
};
CInnerTree.prototype.updateLabelClass = function(labelElem, className, node)
{
labelElem.className = className + " " + CLS_TREE_TEXT;
// update aria-ckecked for the single selection tree, for multiple selection is done in the updateCheckbox function
if (!(this.getSelectionMode() != SINGLE_TREE_SELECTION && this.getSelectTreeUI() == CHECKBOX_TREE) && node) {
updateLabelAriaChecked(labelElem, node)
}
};
/*
* override cancelBub => PRMTUtils.F_StopEvent to avoid duplication of
* several functions which only difference is using cancelBub instead of
* PRMTUtils.F_StopEvent
*/
function cancelBub(evt)
{
return PRMTUtils.F_StopEvent.apply(this, arguments);
}
// get the UINode and TreeNode which are the event target
function getTargetNodeInfo(evt)
{
return getUINodeNodeInfo(getUINode(evt));
}
function getUINodeNodeInfo(uiNode)
{
var result = {};
result.uiNode = uiNode;
var uiNodeTreeRef = uiNode.getAttribute(gsCTREE_treeRef).toString();
//get the tree id
result.tree = uiNode.getAttribute(gsCTREE_tree).toString();
//get tree Node
result.node = getTreeNode(result.tree, uiNodeTreeRef);
return result;
}
function selectNode(evt)
{
//get the event in a cross-browser fashion
evt = (evt) ? evt : ((event) ? event : null);
if ((evt != null) && (evt.keyCode != null) && (evt.keyCode != 13) && (evt.keyCode != 0))
{
return false;
}
//cancel any text selection
clearSelection();
//prevent the event from bubbling to other elements
PRMTUtils.F_StopEvent(evt);
//get UI Node
var uiNode = getUINode(evt);
var uiNodeTreeRef = uiNode.getAttribute(gsCTREE_treeRef).toString();
//get the tree object
var tree = uiNode.getAttribute(gsCTREE_tree).toString();
//get tree Node
var node = getTreeNode(tree, uiNodeTreeRef);
var oTree = node.getTree();
oTree.f_moveFocus(null, node);
oTree.processNodeSelection(node, tree, evt.ctrlKey, evt.shiftKey);
if (oTree.m_oTreeControl)
{
oTree.m_oTreeControl.cacheControlValue();
}
return false;
}
/**
* Process node selection, is called by click and keydown(SPACE) event handlers
*
*/
CInnerTree.prototype.processNodeSelection = function(node, tree, ctrlKey, shiftKey) {
//handle multiple select
if (this.getSelectionMode() != SINGLE_TREE_SELECTION)
{
if ((ctrlKey == false) && (shiftKey == false) && (this.getSelectTreeUI() != CHECKBOX_TREE))
{
this.clearPreviousSelections();
}
var normalTreeNeedsRedraw = ((this.getSelectTreeUI() == NORMAL_TREE) && (ctrlKey == false) && (shiftKey == false));
var unselectNode = ((this.getSelectTreeUI() == CHECKBOX_TREE) || ((this.getSelectTreeUI() == NORMAL_TREE) && ((this.getAllowSelectionToggle() == true) || ((this.getAllowSelectionToggle() == false) && (ctrlKey == true)))));
if (normalTreeNeedsRedraw)
{
this.getRootNode().setSelected(false);
if (this.getTrackSelectionOrder())
{
this.clearSelectionOrder();
}
}
//setSelected
var nodeWasSelected = node.isSelected();
if ((this.getSelectTreeUI() == NORMAL_TREE) && (shiftKey == true))
{
var anchorNode = this.getAnchorNode();
if (anchorNode != null && node.getRootNode().hasSelectedChildren())
{
if (node.getParent() == anchorNode.getParent())
{
var anchorNodeIndex = anchorNode.getIndex();
var nodeIndex = node.getIndex();
var iCurrentNode = anchorNodeIndex;
var iIncrement = ((anchorNodeIndex > nodeIndex)? - 1 : 1);
//select all of the children between the anchor node and the selected node
while (iCurrentNode != nodeIndex + iIncrement)
{
var siblingNode = node.getParent().m_oChildren[iCurrentNode];
siblingNode.setSelected(true);
var oLabel = siblingNode.getLabel(tree);
this.updateLabelClass(oLabel, getClassName(siblingNode, this), siblingNode);
redrawChildren(siblingNode, tree);
iCurrentNode += iIncrement;
}
}
}
}
if (nodeWasSelected == true)
{
if (unselectNode)
{
node.setSelected(false);
this.setLastSelectedNode(null);
this.removeFromPrevSelArray( node.getValue(), node.getName() );
}
}
else
{
node.setSelected(true);
this.setLastSelectedNode(node);
}
node.updateNodeSelection();
node.updateParent();
this.updateLabelClass(node.getLabel(tree), getClassName(node, this), node);
this.checkData();
if (normalTreeNeedsRedraw)
{
this.redraw();
this.checkData();
}
else
{
redrawChildren(node, tree);
redrawParents(node, tree);
}
if (unselectNode && nodeWasSelected)
{
this.setAnchorNode(null);
}
else
{
this.setAnchorNode(node);
}
}
else
{
//single select remove all other selections
this.clearPreviousSelections();
if (node.isSelected() == true && this.getAllowSelectionToggle() == true)
{
this.getRootNode().setSelected(false);
this.setLastSelectedNode(null);
}
else
{
this.getRootNode().setSelected(false);
node.setSelected(true);
this.setLastSelectedNode(node);
}
node.updateParent();
this.redraw();
this.checkData();
}
};
function redrawChildren(node,tree)
{
//has the child node been rendered?
//draw the nodes if they haven't been rendered
if (node.getRendered() == true)
{
var children = node.getChildren();
var oTree = node.getTree();
var childrenContainer = document.getElementById(tree + node.getTreeRef() + "children");
// when redrawing first level (by selecting "More") the container Id has not the "children" suffix
if (childrenContainer === null) {
childrenContainer = document.getElementById(tree + node.getTreeRef());
}
for (var j = 0; j < children.length; j++)
{
var oChild = children[j];
var labelElem = oChild.getLabel(tree);
if (labelElem == null)
{
if (j > 0)
{
oTree.redrawNodeToggle(children[j - 1], tree + children[j - 1].getTreeRef());
}
oTree.draw(oChild, childrenContainer);
if (node.isOpen() == false)
{
document.getElementById(tree + oChild.getTreeRef()).style.display = "none";
}
}
else
{
oTree.updateLabelClass(labelElem, getClassName(oChild, oTree), oChild);
if (oTree.getSelectionMode() != SINGLE_TREE_SELECTION)
{
if (oTree.getSelectTreeUI() == CHECKBOX_TREE)
{
var checkbox = oChild.getCheckbox(tree);
if (checkbox) {
updateCheckboxClass(checkbox, oChild);
}
}
}
}
redrawChildren(oChild,tree);
}
}
}
function redrawParents(node, tree)
{
var parentNode = node.getParent();
if (parentNode != null)
{
var labelElem = parentNode.getLabel(tree);
if (labelElem != null)
{
var v_oTree = parentNode.getTree();
v_oTree.updateLabelClass(labelElem, getClassName(parentNode, v_oTree), parentNode);
if (node.getTree().getSelectionMode() != SINGLE_TREE_SELECTION)
{
if (parentNode.getTreeRef() != null && parentNode.getTreeRef().length != 0)
{
if (node.getTree().getSelectTreeUI() == CHECKBOX_TREE)
{
var checkbox = parentNode.getCheckbox(tree);
updateCheckboxClass(checkbox, parentNode);
}
redrawParents(parentNode, tree);
}
}
}
}
}
function dragStartOnNode(evt)
{
//get the event in a cross-browser fashion
evt = (evt) ? evt : ((event) ? event : null);
//cancel any text selection
clearSelection();
//prevent the event from bubbling to other elements
PRMTUtils.F_StopEvent(evt);
var dragRef = evt.srcElement.getAttribute(gsCTREE_dragRef);
if (typeof dragRef == K_PRMT_sSTRING && dragRef.length != 0)
{
var uiNode = getUINode(evt);
if (uiNode)
{
//get the tree object
var tree = uiNode.getAttribute(gsCTREE_dragTree).toString();
//get tree Node
var node = getTreeNode(tree, dragRef);
var treeObj = node.getTree();
if (!node.isSelected())
{
if ((evt.ctrlKey == false) && (evt.shiftKey == false))
{
treeObj.getRootNode().setSelected(false);
treeObj.clearPreviousSelections();
if (treeObj.getTrackSelectionOrder())
{
treeObj.clearSelectionOrder();
}
}
//select all the children
node.setSelected(true);
//update the parent
node.updateParent();
treeObj.updateLabelClass(node.getLabel(), getClassName(node, treeObj). node);
if ((evt.ctrlKey == false) && (evt.shiftKey == false))
{
treeObj.redraw();
treeObj.checkData();
}
}
var selectedNodes = treeObj.getSelectedFolderNodes();
selectedNodes = selectedNodes.concat(treeObj.getSelectedLeafNodes());
var selNodesStr = tree + "~~~~~";
for (var i = 0; i < selectedNodes.length; i++)
{
if (i > 0)
{
selNodesStr += "~~~";
}
selNodesStr += selectedNodes[i].getTreeRef();
}
event.dataTransfer.setData("Text", selNodesStr);
if (treeObj.getOnDragStart() != null)
{
var dragStartFunction = treeObj.getOnDragStart();
dragStartFunction(evt);
}
}
}
}
/////////////////////
//utility functions
/**
* find the DIV enclosing element for the node where the event occurred
*/
function getUINode (evt, uiNode)
{
if (!uiNode)
{
//get the element that trapped the event in a cross-browser fashion
uiNode = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement : null);
}
while ( uiNode && !(uiNode.tagName == "DIV" && uiNode.getAttribute(gsCTREE_tree) != null) )
{
uiNode = uiNode.parentNode;
}
return uiNode;
}
//return plus or minus icons for the given node
function getToggleSrc(node)
{
if (node.isOpen() == true)
{
if (node.isLastSibling() == true && node.getParent().getMoreData() != true)
{
return TREE_L_MINUS;
}
else
{
return TREE_T_MINUS;
}
}
else
{
if (node.isLastSibling() == true && node.getParent().getMoreData() != true)
{
return TREE_L_PLUS;
}
else
{
return TREE_T_PLUS;
}
}
}
function treeNodeMouseOver(evt)
{
//get the event in a cross-browser fashion
evt = (evt) ? evt : ((event) ? event : null);
//cancel any text selection
clearSelection();
//prevent the event from bubbling to other elements
PRMTUtils.F_StopEvent(evt);
//get UI Node
var uiNode = getUINode(evt);
var uiNodeTreeRef = uiNode.getAttribute(gsCTREE_treeRef).toString();
//get the tree object
var tree = uiNode.getAttribute(gsCTREE_tree).toString();
//get tree Node
var node = getTreeNode(tree, uiNodeTreeRef);
window.status = K_PRMT_sEMPTY;
var v_oTree = node.getTree();
if (v_oTree) v_oTree.treeNodeShowFocus(node, tree);
}
CInnerTree.prototype.treeNodeShowFocus = function(node, tree)
{
if (node.getNodeTypeObject().getSelectable() && node.isSelected() == false && node.hasSelectedChildren() == false)
{
this.updateLabelClass(node.getLabel(tree), CLS_TREE_NODE_HOVER, node);
}
};
CInnerTree.prototype.treeNodeHideFocus = function(node, tree)
{
if (node.isSelected() == false && node.hasSelectedChildren() == false)
{
this.updateLabelClass(node.getLabel(tree), CLS_TREE_NODE_UNSELECTED, node);
}
};
function treeNodeMouseOut(evt)
{
//get the event in a cross-browser fashion
evt = (evt) ? evt : ((event) ? event : null);
//cancel any text selection
clearSelection();
//prevent the event from bubbling to other elements
PRMTUtils.F_StopEvent(evt);
//get UI Node
var uiNode = getUINode(evt);
var uiNodeTreeRef = uiNode.getAttribute(gsCTREE_treeRef).toString();
//get the tree object
var tree = uiNode.getAttribute(gsCTREE_tree).toString();
//get tree Node
var node = getTreeNode(tree, uiNodeTreeRef);
window.status = K_PRMT_sEMPTY;
var v_oTree = node.getTree();
if (v_oTree) v_oTree.treeNodeHideFocus(node, tree);
}
/////////////////////////////////
// Tree node object
// oParentTreeNode: the parent node - null for the root node
// oTreeNodeType: the type of node, a TreeNodeType object (e.g. folder/leaf)
// bOpenState: if this is a container, whether the the default state is open or closed [true|false]
// name: the display value for the tree node
// value: the use value for the tree node
// bSelected: whether this node has been selected or not
//Tree nodes
function CInnerTreeNode(oParentTreeNode, oTreeNodeType, bOpenState, sName, value, bSelected)
{
if (oTreeNodeType)
{
this.init(oParentTreeNode, oTreeNodeType, bOpenState, sName, value, bSelected);
}
}
CInnerTreeNode.prototype = new CTreeNode();
CInnerTreeNode.prototype.isFirst = function ()
{
var v_bResult = false;
if ((this.getParent() != null) && (this.getParent() == this.getRootNode()) && (this.getTreeRef() == this.getParent().m_oChildren[0].getTreeRef()))
{
v_bResult = true;
}
return v_bResult;
};
CInnerTreeNode.prototype.isFirstSibling = function ()
{
var v_bResult = false;
if ((this.getParent() != null) && (this.getTreeRef() == this.getParent().m_oChildren[0].getTreeRef()))
{
v_bResult = true;
}
return v_bResult;
};
CInnerTreeNode.prototype.isLastSibling = function ()
{
var v_bResult = false;
if ((this.getParent() != null) && (this.getTreeRef() == this.getParent().m_oChildren[this.getParent().getChildrenLength() - 1].getTreeRef()))
{
v_bResult = true;
}
return v_bResult;
};
CInnerTreeNode.prototype.getNextSibling = function ()
{
var v_oResult = null;
if (! this.isLastSibling())
{
v_oResult = this.getParent().m_oChildren[this.getIndex() + 1];
}
return v_oResult;
};
CInnerTreeNode.prototype.getPreviousSibling = function ()
{
var v_oResult = null;
if (! this.isFirstSibling())
{
v_oResult = this.getParent().m_oChildren[this.getIndex() - 1];
}
return v_oResult;
};
CInnerTreeNode.prototype.getLabel = function (sTreeRef)
{
if (!this.m_oLabelText) {
this.m_oLabelText = document.getElementById(sTreeRef + this.getTreeRef() + gsCTREE_labelText);
}
return this.m_oLabelText;
};
CInnerTreeNode.prototype.getLabelContainer = function (treeName)
{
return document.getElementById(treeName + this.getTreeRef() + gsCTREE_labelText);
};
CInnerTreeNode.prototype.getNodeLabel = function ()
{
var v_oTree = this.getTree();
var v_sTreeRef = v_oTree.getName();
if (!this.m_oLabelText) {
this.m_oLabelText = document.getElementById(sTreeRef + this.getTreeRef() + gsCTREE_labelText);
}
return this.m_oLabelText;
};
//boolean: returns whether the node has children or not
CInnerTreeNode.prototype.hasChildren = function ()
{
return(this.getChildrenLength() > 0);
};
CInnerTreeNode.prototype.updateNodeSelection = function ()
{
var v_oTree = this.getTree();
if (v_oTree.getSelectTreeUI() == NORMAL_TREE)
{
if (v_oTree.getSelectionMode() == CONTIGUOUS_TREE_SELECTION && this.isSelected() == false && this.getNodeType() == TREE_FOLDER && this.getChildrenLength() == this.getSelectedChildrenCount()) {
this.m_bSelected = true;
}
var labelElem = this.getLabel(this.getTree().getName());
if (labelElem != null) {
v_oTree.updateLabelClass(labelElem, getClassName(this, v_oTree), this);
}
}
else
{
var checkbox = this.getCheckbox(v_oTree.getName());
if (checkbox != null) {
updateCheckboxClass(checkbox, this);
}
}
};
//open: specifies whether the children of a container node should be displayed
CInnerTreeNode.prototype.isClosed = function ()
{
return !this.m_bOpen;
};
//return the child at the appropriate position
CInnerTreeNode.prototype.getFirstChild = function ()
{
var v_oResult = null;
if ( this.getChildrenLength() > 0 )
{
v_oResult = this.m_oChildren[0];
}
return v_oResult;
};
//return the child at the appropriate position
CInnerTreeNode.prototype.getLastChild = function ()
{
var v_oResult = null;
if ( this.getChildrenLength() > 0 )
{
v_oResult = this.m_oChildren[this.getChildrenLength() - 1];
}
return v_oResult;
};
var TREE_IMG =
{
'TREE_L':
{
'MINUS': TREE_L_MINUS,
'PLUS' : TREE_L_PLUS,
'ONLY' : TREE_L_ONLY
},
'TREE_T':
{
'MINUS': TREE_T_MINUS,
'PLUS' : TREE_T_PLUS,
'ONLY' : TREE_T_ONLY
}
};
// overrides parent method to create a new node of the same class
CInnerTreeNode.prototype.createNewNode = function(treeNode, tntGeneric,name, value, isSelected)
{
// ( oParentTreeNode, oTreeNodeType, bOpenState, sName, value, bSelected )
new CInnerTreeNode(treeNode, tntGeneric, false, jsDecodeStr(name), jsDecodeStr(value), isSelected);
};
function updateCheckboxClass(checkbox, node)
{
var checkBoxClass = K_PRMT_sEMPTY;
var checked = true;
var ariaChecked = "true";
//get the current state
switch (node.getState())
{
case NODE_UNSELECTED:
checkBoxClass = K_PRMT_CSS_CHECKBOX;
checked = false;
ariaChecked = "false";
break;
case NODE_PARTIAL:
checkBoxClass = K_PRMT_CSS_CHECKBOX_PARTIAL;
ariaChecked = "mixed";
break;
case NODE_SELECTED:
checkBoxClass = K_PRMT_CSS_CHECKBOX_CHECKED;
break;
}
checkbox.className = checkBoxClass;
checkbox.firstChild.checked = checked;
checkbox.firstChild.setAttribute("checked", checked);
updateLabelAriaChecked(node.getLabel(node.getTree().getName()), node, ariaChecked);
}
/**
*
*/
function updateLabelAriaChecked(labelElem, node, ariaChecked)
{
if (typeof ariaChecked == K_PRMT_sUNDEFINED) {
ariaChecked = node2AriaChecked(node);
}
if (labelElem) {
if (labelElem[K_PRMT_ARIA_CHECKED]) {
labelElem[K_PRMT_ARIA_CHECKED] = ariaChecked;
}
else {
labelElem.setAttribute(K_PRMT_ARIA_CHECKED, ariaChecked);
}
}
}
/**
* Maps the aria-checked to the node state : NODE_UNSELECTED => "false", NODE_PARTIAL => "mixed", NODE_SELECTED => "true"
*/
function node2AriaChecked(node)
{
if (node && node.getState) {
var nodeState = node.getState();
return (nodeState == NODE_UNSELECTED? "false" :(nodeState == NODE_PARTIAL? "mixed":"true"));
}
}
function updateToggleIcon(oNode, sTreeName)
{
//update the icons
var icon = document.getElementById(sTreeName + oNode.getTreeRef() + gsCTREE_icon);
if (icon)
{
//icon.src = getIconSrc(oNode);
var toggleIcon = document.getElementById(sTreeName + oNode.getTreeRef() + gsCTREE_toggle + oNode.getTreeHierarchy());
//toggleIcon.src = getToggleSrc(oNode);
toggleIcon.className = getToggleClassName(oNode);
toggleIcon.title = getToggleTitle(oNode);
var toggleText = ((toggleIcon.className == K_PRMT_TREE_TOGGLE_OPENED + oNode.m_oRoot.m_oTree.m_sDirection) ? "-" : "+");
var v_oTextSpanNode = toggleIcon.nextSibling;
if (v_oTextSpanNode.textContent) {
v_oTextSpanNode.textContent = toggleText;
} else { //support IE
v_oTextSpanNode.firstChild.data = toggleText;
}
}
}
//return plus or minus icons for the given node
function getToggleClassName(node)
{
if (node.isOpen() == true)
{
return ( K_PRMT_TREE_TOGGLE_OPENED + node.m_oRoot.m_oTree.m_sDirection );
}
else
{
return ( K_PRMT_TREE_TOGGLE_CLOSED + node.m_oRoot.m_oTree.m_sDirection );
}
}