CInnerTree.js 57 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941
  1. /*
  2. *+------------------------------------------------------------------------+
  3. *| Licensed Materials - Property of IBM
  4. *| BI and PM: prmt
  5. *| (C) Copyright IBM Corp. 2002, 2020
  6. *|
  7. *| US Government Users Restricted Rights - Use, duplication or
  8. *| disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  9. *|
  10. *+------------------------------------------------------------------------+
  11. */
  12. //TREE CONTROL
  13. // oPane: the HTML element where the tree will be rendered
  14. // oSubmit: the form control to submit selections to the server
  15. // bRequired: is this a required field [true|false]
  16. // bMultiSelect: can the user pick more than one value [true|false]
  17. // sRef: the name of this object
  18. // oImgTest: the image object used for validation handling
  19. // oErrorFeedback: object used to provide validation feedback
  20. // sCVId
  21. // sStyle
  22. // sTextDir
  23. // sPromptName: the name of the prompt associated with the tree. This is used as a cache key prefix
  24. CInnerTree.prototype = new CTree;
  25. function CInnerTree(oPane, oSubmit, bRequired, bMultiSelect, sRef, oImgTest, oErrorFeedback, sCVId, sStyle, sTextDir, sPromptName, oPromptControl)
  26. {
  27. this.setCVId(sCVId);
  28. this.m_style = sStyle;
  29. this.m_sTextDir = sTextDir;
  30. //html div element where adornments will be rendered
  31. this.m_oOuterPane = oPane;
  32. //html element where the tree will be rendered
  33. this.m_oPane = null;
  34. var v_sCustomDir = cssParser( sStyle, "direction", true );
  35. var v_sFinalDir = ((v_sCustomDir == "ltr" || v_sCustomDir == "rtl") ? v_sCustomDir : PRMT_BidiUtils.lookupDirection(oPane));
  36. this.m_sDirection = ( v_sFinalDir == "rtl" ? "RTL" : "");
  37. //create a root node for the tree
  38. //new nodes are added by calling the appendChild method for each node
  39. this.m_oRoot = new CInnerTreeNode(null, tntRoot, true, 'root', 'root', false);
  40. this.m_oRoot.m_oTree = this;
  41. this.m_oRoot.setTreeRef(K_PRMT_sEMPTY);
  42. this.m_oSubmit = oSubmit;
  43. this.m_bRequired = bRequired;
  44. //determine the selection mode for the tree
  45. if (bMultiSelect == false)
  46. {
  47. this.m_iSelectionMode = SINGLE_TREE_SELECTION;
  48. this.m_sSelectTreeUI = NORMAL_TREE;
  49. }
  50. else
  51. {
  52. this.m_iSelectionMode = DISCONTIGUOUS_TREE_SELECTION;
  53. this.m_sSelectTreeUI = CHECKBOX_TREE;
  54. }
  55. //check the state of the control?
  56. //this needs to happen after the nodes are added
  57. this.m_bValid = false;
  58. this.m_sRef = sRef;
  59. //maintain a list of selections
  60. this.m_sTreeProcessResult = K_PRMT_sEMPTY;
  61. this.m_oErrorFeedback = oErrorFeedback;
  62. //../prompting/images for handling errors
  63. this.m_oImgCheck = oImgTest;
  64. if (this.m_oImgCheck != null)
  65. {
  66. this.m_oImgErrorFalse= new Image();
  67. this.m_oImgErrorFalse.src = ERROR_TIMED_SMALL_OFF;
  68. this.m_oImgErrorTrue = new Image();
  69. this.m_oImgErrorTrue.src = ERROR_TIMED_SMALL;
  70. }
  71. this.m_bShowRootNode = false;
  72. this.m_bLoadOnTheFly = false;
  73. this.m_iIsLoading = 0;
  74. this.m_bForceSelectionAtLowestLevel = false;
  75. this.m_bAllowSelectionToggle = true;
  76. this.m_oAnchorNode = null;
  77. this.m_bAllowDragDrop = false;
  78. this.m_fOnDragStartFunc = null;
  79. this.m_fOnDragFunc = null;
  80. this.m_fOnDragEndFunc = null;
  81. this.m_fOnContextMenu = null;
  82. this.m_bTrackSelectionOrder = false;
  83. this.m_aSelectionOrder = [];
  84. this.m_fSingleClickFunc = null;
  85. this.m_fDoubleClickFunc = null;
  86. this.m_bHideAdornments = false;
  87. this.m_bMustChangeDefault = false;
  88. this.m_bHideOuterTable = false;
  89. this.m_bRecursiveSelect = true;
  90. this.m_bPromptTree = false;
  91. this.m_iMaxValueCount = 5000;
  92. this.m_bShowPreviousValues = true;
  93. this.m_aAllSelections = null;
  94. this.m_iContainerWidth = null;
  95. this.m_iContainerHeight = null;
  96. this.m_bNodesCanHaveChildren = true;
  97. this.m_bIsDisabled = false;
  98. this.m_bHasBeenDrawn = false;
  99. this.m_oLastSelectedNode = null;
  100. //skin folder
  101. this.m_sSkin = (typeof getPromptSkin != K_PRMT_sUNDEFINED ? getPromptSkin() : K_PRMT_sDEFAULTSKIN);
  102. if (typeof gDispatcher != K_PRMT_sUNDEFINED) // Try to find global dispatcher object first
  103. {
  104. this.m_oDispatcher = gDispatcher;
  105. }
  106. else if (typeof CDispatcher != K_PRMT_sUNDEFINED)
  107. {
  108. this.m_oDispatcher = new CDispatcher();
  109. }
  110. else
  111. {
  112. this.m_oDispatcher = null;
  113. }
  114. this.m_sServerPath = this.getGateway();
  115. // DOM objects used to create child nodes.
  116. this.m_oTREELINE = document.createElement("IMG");
  117. this.m_oTREELINE.src = PROMT_IMAGES + "blank.gif";
  118. this.m_oTREELINE.alt = "";
  119. this.m_oTREELINE.className = "clsTreeLineIcon";
  120. this.m_oTREELINE.align = gsCTREE_middle;
  121. this.m_oTREELINE.setAttribute(gsCTREE_treeRef, gsCTREE_img);
  122. this.m_oDIVnewElement = document.createElement("DIV");
  123. this.m_oDIVGroupElement = document.createElement("DIV");
  124. this.m_oDIVGroupElement.setAttribute(K_PRMT_ARIA_ROLE,K_PRMT_TREE_ROLE_GROUP);
  125. this.m_oNOBR = document.createElement("NOBR");
  126. this.m_oNOBR.setAttribute(gsCTREE_treeRef, gsCTREE_nobr);
  127. this.m_oIcon = document.createElement("IMG");
  128. this.m_oIcon.setAttribute(gsCTREE_treeRef, gsCTREE_img);
  129. this.m_oIndicatorSPAN = document.createElement("SPAN");
  130. this.m_oIndicatorSPAN.style.paddingLeft = 3;
  131. this.m_oIndicatorIMG = document.createElement("IMG");
  132. this.m_oIndicatorIMG.align = gsCTREE_middle;
  133. this.m_oTextSPAN = document.createElement("SPAN");
  134. this.m_oToggleIMG = document.createElement("IMG");
  135. this.m_oToggleIMG.align = gsCTREE_middle;
  136. this.m_oToggleIMG.onclick = null;
  137. this.m_oToggleIMG.src = (this.m_sDirection == "RTL" ? TREE_L_ONLY_RTL : TREE_L_ONLY);
  138. this.m_oCheckIMG = document.createElement("IMG");
  139. this.m_oCheckIMG.align = gsCTREE_middle;
  140. /*RTC 364636: BUG: [WA][IE11] Tree Checkbox checkmarks do not update correctly*/
  141. var isIE11 = !!navigator.userAgent.match(/Trident.*rv\:11\./);
  142. this.m_oCheckDIV = isIE11? createCheckBoxTable() : document.createElement("DIV");
  143. var checkBoxInputParent = isIE11? this.m_oCheckDIV.getElementsByTagName('div')[0] : this.m_oCheckDIV;
  144. var v_oCheckInput = document.createElement("INPUT");
  145. v_oCheckInput.type = "checkbox";
  146. v_oCheckInput.tabIndex = -1;
  147. v_oCheckInput.className = "dijitCheckBoxInput";
  148. checkBoxInputParent.appendChild(v_oCheckInput);
  149. this.m_oLabelSPAN = document.createElement("SPAN");
  150. this.m_oAncestry = null;
  151. if (sPromptName)
  152. {
  153. this.setAllowStateCache(SYSTEMPROPERTY_TREE_CACHE_ENABLED, sPromptName);
  154. }
  155. if (oPromptControl)
  156. {
  157. this.savePromptControlRef(oPromptControl);
  158. }
  159. }
  160. function createCheckBoxTable()
  161. {
  162. var table = document.createElement("table");
  163. var tr = document.createElement("tr");
  164. var td = document.createElement("td");
  165. var div = document.createElement("div");
  166. td.appendChild(div);
  167. tr.appendChild(td);
  168. table.appendChild(tr);
  169. return table;
  170. };
  171. // * CInnerTree.prototype = new CPromptControl();
  172. // Set this to the tree's parameter name if this is a prompt control tree
  173. // getPromptValues OM function will be called automatically if this is a prompting tree
  174. CInnerTree.prototype.redrawNodeToggle = function(node, nodeId)
  175. {
  176. var newToggleIcon = document.getElementById(nodeId + gsCTREE_toggle + node.getTreeHierarchy());
  177. if (newToggleIcon != null)
  178. {
  179. this.detailToogleIcon(node, newToggleIcon);
  180. }
  181. };
  182. CInnerTree.prototype.drawLoading = function(node, nodeId)
  183. {
  184. var theElement = document.getElementById(nodeId);
  185. if (!theElement && node.getNodeType() == TREE_ROOT && this.getRootNodeShowing() == false)
  186. {
  187. theElement = this.m_oPane;
  188. }
  189. if (theElement != null)
  190. {
  191. var newDivContainer = document.createElement("DIV");
  192. newDivContainer.className = CLS_TREE_LEVEL;
  193. newDivContainer.id = this.getName() + node.getTreeRef() + "loading";
  194. newDivContainer.style.width = "100%";
  195. var newNobrContainer = document.createElement("NOBR");
  196. this.drawTreeLines(node, newNobrContainer, node.getLevel() + 1);
  197. if (!(node.getNodeType() == TREE_ROOT && node.getTree().getRootNodeShowing() == false && node.getMoreData() != true))
  198. {
  199. var newLIcon = document.createElement("IMG");
  200. newLIcon.align = gsCTREE_middle;
  201. newLIcon.src = (this.m_sDirection == "RTL" ? TREE_L_ONLY_RTL : TREE_L_ONLY);
  202. newNobrContainer.appendChild(newLIcon);
  203. }
  204. var newStateIcon = document.createElement("IMG");
  205. newStateIcon.align = gsCTREE_middle;
  206. newStateIcon.src = TREE_LOADING;
  207. newNobrContainer.appendChild(newStateIcon);
  208. var newLabelContainer = document.createElement("SPAN");
  209. newLabelContainer.className = CLS_TREE_NODE_UNSELECTED + K_PRMT_sSP + CLS_TREE_TEXT;
  210. //We need the localized string for "Loading..." here
  211. if (typeof PMT_TRE_TREE_LOADING != K_PRMT_sUNDEFINED)
  212. {
  213. var newStateText = document.createTextNode(PMT_TRE_TREE_LOADING);
  214. newLabelContainer.appendChild(newStateText);
  215. newLabelContainer.title = PMT_TRE_TREE_LOADING;
  216. }
  217. newNobrContainer.appendChild(newLabelContainer);
  218. newDivContainer.appendChild(newNobrContainer);
  219. theElement.appendChild(newDivContainer);
  220. }
  221. };
  222. CInnerTree.prototype.drawMoreData = function(node, nodeId)
  223. {
  224. var theElement = document.getElementById(nodeId);
  225. if (!theElement && node.getNodeType() == TREE_ROOT && this.getRootNodeShowing() == false)
  226. {
  227. theElement = this.m_oPane;
  228. }
  229. var childrenContainer = (theElement.getAttribute("role") == "tree"? theElement : theElement.firstChild.nextSibling);
  230. if (theElement != null && childrenContainer != null && (childrenContainer.getAttribute("role") == "group" || childrenContainer.getAttribute("role") == "tree"))
  231. {
  232. var newDivContainer = document.createElement("DIV");
  233. newDivContainer.className = CLS_TREE_LEVEL;
  234. newDivContainer.id = this.getName() + node.getTreeRef() + "moredata";
  235. newDivContainer.style.width = "100%";
  236. var newNobrContainer = document.createElement("NOBR");
  237. this.drawTreeLines(node, newNobrContainer, node.getLevel() + 1);
  238. var newLIcon = document.createElement("IMG");
  239. newLIcon.align = gsCTREE_middle;
  240. newLIcon.src = (this.m_sDirection == "RTL" ? TREE_L_ONLY_RTL : TREE_L_ONLY);
  241. newNobrContainer.appendChild(newLIcon);
  242. var newStateIcon = document.createElement("IMG");
  243. newStateIcon.align = gsCTREE_middle;
  244. newStateIcon.src = TREE_MORE_DATA;
  245. newNobrContainer.appendChild(newStateIcon);
  246. var newLabelContainer = document.createElement("SPAN");
  247. newLabelContainer.className = CLS_TREE_NODE_UNSELECTED + K_PRMT_sSP + CLS_TREE_TEXT_LINK;
  248. //We need the localized string for "More" here
  249. if (typeof PMT_TRE_MORE != K_PRMT_sUNDEFINED)
  250. {
  251. var newStateText = document.createTextNode(PMT_TRE_MORE);
  252. newLabelContainer.appendChild(newStateText);
  253. newLabelContainer.title = PMT_TRE_MORE;
  254. }
  255. newLabelContainer.id = this.getName() + node.getTreeRef() + "moredatalabel";
  256. newLabelContainer.setAttribute(gsCTREE_tree, this.getName());
  257. newLabelContainer.setAttribute(gsCTREE_treeRef, node.getTreeRef());
  258. newLabelContainer.tabIndex = 0;
  259. PRMTUtils.f_addEvent(newLabelContainer, "click", getMoreDataForTreeNode);
  260. PRMTUtils.f_addEvent(newLabelContainer, "keydown", getMoreDataForTreeNode);
  261. PRMTUtils.f_addEvent(newLabelContainer, "keypress", getMoreDataForTreeNode);
  262. newNobrContainer.appendChild(newLabelContainer);
  263. newDivContainer.appendChild(newNobrContainer);
  264. childrenContainer.appendChild(newDivContainer);
  265. }
  266. };
  267. CInnerTree.prototype.drawTreeLines = function(node, newElement, drawToLevel)
  268. {
  269. // put in appropriate spacers
  270. if (drawToLevel > 1)
  271. {
  272. for (var n = 1; n < drawToLevel; n++)
  273. {
  274. var spacerIcon = this.m_oTREELINE.cloneNode(true);
  275. var oParent = node.getParentAtLevel(n);
  276. if (oParent.isLastSibling() == true && oParent.getParent().getMoreData() != true)
  277. {
  278. //if the parent was last
  279. spacerIcon.className = spacerIcon.className + " clsTreeLineIconSpace";
  280. }
  281. newElement.appendChild(spacerIcon);
  282. }
  283. }
  284. };
  285. CInnerTree.prototype.drawOuterTable = function()
  286. {
  287. if (this.m_oOuterPane != null)
  288. {
  289. var sId = this.m_sRef;
  290. var sStyle = this.getStyle();
  291. var HTMLOut = "<fieldset class='clsFieldSet' style='" + cssParser(sStyle, gsCSS_DEFAULT_STYLE + ',height') +"'><table cellpading='0' cellspacing='0' border='0' onclick='treeContainerClicked(event)' class='clsPromptComponent' style='"+cssParser(sStyle,"visibility,height")+"'>" +
  292. "<tr>";
  293. if (this.getHideAdornments() != true)
  294. {
  295. HTMLOut += "<td valign='top' width='10px'>" +
  296. "<table cellpadding='0' cellspacing='0' border='0' width='10' height='20'>";
  297. if (this.getRequired() == true)
  298. {
  299. HTMLOut += "<tr>" +
  300. "<td valign='top'><img src='" + this.m_sSkin + "/prompting/images/icon_required.gif' class='clsErrorRequired' align='top' height='10' width='10' border='0'/></td>" +
  301. "</tr>";
  302. }
  303. // put the tree in the tab order relative to tree's position in the page (tabindex=-1)
  304. HTMLOut += "<tr>" +
  305. "<td valign='middle'><img id='imgTest_tree" + sId + "' name='imgTest_tree" + sId + "' class='clsErrorRequired' src='" + this.m_sSkin + "/prompting/images/error_timed_small_off.gif' align='bottom' height='10' width='10' border='0'/></td>" +
  306. "</tr>" +
  307. "</table>" +
  308. "</td>";
  309. }
  310. HTMLOut += "<td>" +
  311. "<table cellpadding='0' cellspacing='0' border='0' width='100%'>" +
  312. "<tr>" +
  313. "<td><div id='treePane" + sId + "' tabindex='-1' class='clsTreePane pa'";
  314. if (this.getContainerWidth() != null || this.getContainerHeight() != null)
  315. {
  316. HTMLOut += " style='";
  317. if (this.getContainerWidth() != null) {
  318. HTMLOut += "width:" + this.getContainerWidth() + ";";
  319. }
  320. if (this.getContainerHeight() != null) {
  321. HTMLOut += "height:" + this.getContainerHeight() + ";";
  322. }
  323. HTMLOut += "'";
  324. }
  325. HTMLOut += "></div></td>" +
  326. "</tr>";
  327. if (this.getHideAdornments() != true)
  328. {
  329. HTMLOut += "<tr>" +
  330. "<td><div id='feedback_tree" + sId + "' class='clsFeedbackWidget'><IMG name='sizer_tree" + sId + "' src='" + this.m_sSkin + "/prompting/images/spacer.gif' alt='' width='100%' height='3'/></div></td>" +
  331. "</tr>";
  332. }
  333. if (this.getSelectionMode() != SINGLE_TREE_SELECTION)
  334. {
  335. HTMLOut += "<tr>" +
  336. "<td align='right'>";
  337. if (this.getSelectTreeUI() != CHECKBOX_TREE || this.getSelectionMode() != DISCONTIGUOUS_TREE_SELECTION) {
  338. HTMLOut += "<A href='javascript:" + sId + ".selectAll()' class='clsLink pl'>" + PMT_UIM_SELECTALL + "</A>&nbsp;";
  339. }
  340. HTMLOut += "<A href='javascript:" + sId + ".deSelectAll()' class='clsLink pl'>" + PMT_UIM_DESELECTALL + "</A>" +
  341. "</td>" +
  342. "</tr>";
  343. }
  344. HTMLOut += "</table>" +
  345. "</td>" +
  346. "</tr>" +
  347. "</table></fieldset>";
  348. this.m_oOuterPane.innerHTML = HTMLOut;
  349. if (this.getErrorFeedbackWidget() == null) {
  350. this.setErrorFeedbackWidget(document.getElementById("feedback_tree" + sId));
  351. }
  352. if (this.getImgCheck() == null)
  353. {
  354. this.setImgCheck(document.getElementById("imgTest_tree" + sId));
  355. if (this.getImgCheck() != null)
  356. {
  357. this.setImgErrorFalse(ERROR_TIMED_SMALL_OFF);
  358. this.setImgErrorTrue(ERROR_TIMED_SMALL);
  359. }
  360. }
  361. }
  362. };
  363. CInnerTree.prototype.createElementIndicator = function(node, treeName, treeRef)
  364. {
  365. // create indicator span
  366. var newElementIndicator = this.m_oIndicatorSPAN.cloneNode(true);
  367. newElementIndicator.id = treeName + treeRef + gsCTREE_indicatorSpan;
  368. newElementIndicator.setAttribute(gsCTREE_treeRef, treeRef);
  369. newElementIndicator.setAttribute(gsCTREE_dragRef, treeRef.toString());
  370. newElementIndicator.setAttribute(gsCTREE_dragTree, treeName);
  371. newElementIndicator.setAttribute(gsCTREE_tree, treeName);
  372. // create the indicator image
  373. var newElementIndicatorImage = this.m_oIndicatorIMG.cloneNode(true);
  374. newElementIndicatorImage.id = treeName + treeRef + gsCTREE_indicator;
  375. newElementIndicatorImage.setAttribute(gsCTREE_treeRef, treeRef);
  376. newElementIndicatorImage.setAttribute(gsCTREE_dragRef, treeRef.toString());
  377. newElementIndicatorImage.setAttribute(gsCTREE_dragTree, treeName);
  378. newElementIndicatorImage.setAttribute(gsCTREE_tree, treeName);
  379. // set the image
  380. newElementIndicatorImage.src = node.getIndicator();
  381. // add this into the span
  382. newElementIndicator.appendChild(newElementIndicatorImage);
  383. return newElementIndicator;
  384. };
  385. CInnerTree.prototype.draw = function(node, oParentElement)
  386. {
  387. if (node.getTree().getDisabled() == true)
  388. {
  389. return false;
  390. }
  391. var treeRef = node.getTreeRef();
  392. var treeName = this.getName();
  393. //if the node is the root node, removes the old root node so that the entire tree is redrawn
  394. //this takes care of the case where a loading tree is replaced with real data
  395. if (node.getNodeType() == TREE_ROOT)
  396. {
  397. var rootNode = document.getElementById(treeName);
  398. if (rootNode != null) {
  399. oParentElement.removeChild(rootNode);
  400. }
  401. oParentElement.setAttribute(gsCTREE_treeRef, treeRef);
  402. oParentElement.setAttribute(gsCTREE_tree, treeName);
  403. }
  404. // clone outer container DIV (it's much faster than create a new one)
  405. var nodeElement = this.m_oDIVnewElement.cloneNode(true);
  406. PRMTUtils.f_addEvent( nodeElement, "dragstart", dragStartOnNode );
  407. PRMTUtils.f_addEvent( nodeElement, "drag", dragOnNode );
  408. PRMTUtils.f_addEvent( nodeElement, "dragend", dragEndOnNode );
  409. nodeElement.setAttribute(gsCTREE_treeRef, treeRef);
  410. nodeElement.setAttribute(gsCTREE_tree, treeName);
  411. if (treeRef == K_PRMT_sEMPTY) {
  412. nodeElement.setAttribute(K_PRMT_ARIA_ROLE, K_PRMT_TREE_ROLE_TREE);
  413. }
  414. nodeElement.id = treeName + treeRef;
  415. if (!(node.getNodeType() == TREE_ROOT && this.getRootNodeShowing() == false))
  416. {
  417. this.drawNode(node, nodeElement);
  418. }
  419. // ******************************************************************
  420. // deal with children
  421. // ******************************************************************
  422. oParentElement.appendChild(nodeElement);
  423. this.drawNodeChildren (node, nodeElement);
  424. this.m_bHasBeenDrawn = true;
  425. };
  426. /**
  427. * Draws the icon + / - that acts as a toogle for the branch
  428. *
  429. */
  430. CInnerTree.prototype.drawToogleIcon = function(node) {
  431. var newToggleIcon = this.m_oToggleIMG.cloneNode(true);
  432. newToggleIcon.src = PROMT_IMAGES + "blank.gif";
  433. return this.detailToogleIcon(node, newToggleIcon);
  434. };
  435. CInnerTree.prototype.detailToogleIcon = function(node, newToggleIcon) {
  436. // text for high contrast
  437. var newToggleText = this.m_oTextSPAN.cloneNode(true);
  438. newToggleText.className= K_PRMT_TREE_TOGGLE_TEXT;
  439. newToggleText.setAttribute(K_PRMT_ARIA_ROLE, K_PRMT_ARIA_ROLE_PRESENTATION);
  440. var toggleTextContent = "";
  441. if (node.canHaveChildren() == true)
  442. {
  443. if (node.isOpen() == true)
  444. {
  445. newToggleIcon.className = K_PRMT_TREE_TOGGLE_OPENED + this.m_sDirection;
  446. newToggleIcon.title = PMT_TRE_COLLAPSE;
  447. newToggleIcon.alt = PMT_TRE_COLLAPSE;
  448. toggleTextContent = "-";
  449. }
  450. else
  451. {
  452. newToggleIcon.className= K_PRMT_TREE_TOGGLE_CLOSED + this.m_sDirection;
  453. newToggleIcon.title = PMT_TRE_EXPAND;
  454. newToggleIcon.alt = PMT_TRE_EXPAND;
  455. toggleTextContent = "+";
  456. }
  457. newToggleIcon.tabIndex = -1;
  458. newToggleIcon.onclick = toggle;
  459. newToggleText.onclick = toggle;
  460. }
  461. else
  462. {
  463. newToggleIcon.className= K_PRMT_TREE_TOGGLE_LEAF;
  464. newToggleIcon.src = PROMT_IMAGES + "blank.gif";
  465. newToggleIcon.alt = "";
  466. newToggleIcon.onclick = null;
  467. }
  468. var toggleTextNode= document.createTextNode(toggleTextContent);
  469. newToggleText.appendChild(toggleTextNode);
  470. newToggleIcon.setAttribute(gsCTREE_treeRef, gsCTREE_img);
  471. return [newToggleIcon, newToggleText];
  472. };
  473. /**
  474. * Draws the checkbox
  475. *
  476. */
  477. CInnerTree.prototype.drawNodeCheckboxIcon = function(node) {
  478. var newCheckBox = this.m_oCheckDIV.cloneNode(true);
  479. updateCheckboxClass(newCheckBox, node);
  480. newCheckBox.setAttribute(gsCTREE_treeRef, gsCTREE_checkbox);
  481. //set up events
  482. if ((node.getTree().getForceSelectionAtLowestLevel() == true && node.getNodeType() == TREE_ITEM) || (node.getTree().getForceSelectionAtLowestLevel() == false))
  483. {
  484. PRMTUtils.f_addEvent(newCheckBox.firstChild, "click", selectNode);
  485. }
  486. return newCheckBox;
  487. };
  488. /**
  489. * Draws the label <span>Node label</span>
  490. *
  491. */
  492. CInnerTree.prototype.drawNodeLabel = function(node, treeName, treeRef) {
  493. var nodeElementLabelContainer = this.m_oLabelSPAN.cloneNode(true);
  494. nodeElementLabelContainer.id = treeName + treeRef + gsCTREE_labelText;
  495. this.updateLabelClass(nodeElementLabelContainer, getClassName(node, this), node);
  496. nodeElementLabelContainer.setAttribute(gsCTREE_treeRef, treeRef);
  497. nodeElementLabelContainer.setAttribute(gsCTREE_dragRef, treeRef.toString());
  498. nodeElementLabelContainer.setAttribute(gsCTREE_dragTree, treeName);
  499. nodeElementLabelContainer.setAttribute(gsCTREE_tree, treeName);
  500. nodeElementLabelContainer.setAttribute(K_PRMT_ARIA_ROLE, K_PRMT_TREE_ROLE_TREEITEM);
  501. node.m_oLabelText = nodeElementLabelContainer;
  502. if (node.isFirst()) {
  503. nodeElementLabelContainer.tabIndex = 0;
  504. this.m_lastFocus = nodeElementLabelContainer;
  505. }
  506. var labelText = document.createTextNode( G_IsBidiEnabled && this.m_sTextDir ? PRMT_BidiUtils.enforceBidiDirection(node.getName(), this.m_sTextDir) : node.getName() );
  507. nodeElementLabelContainer.appendChild(labelText);
  508. updateLabelAriaChecked(nodeElementLabelContainer, node);
  509. var sStyle = this.getStyle();
  510. nodeElementLabelContainer.style.color= cssParser(sStyle,"color",true);
  511. nodeElementLabelContainer.style.backgroundColor= cssParser(sStyle,"background-color",true);
  512. nodeElementLabelContainer.style.fontFamily= cssParser(sStyle,"font-family",true);
  513. nodeElementLabelContainer.style.fontSize= cssParser(sStyle,"font-size",true);
  514. nodeElementLabelContainer.style.fontWeight= cssParser(sStyle,"font-weight",true);
  515. nodeElementLabelContainer.style.fontStyle= cssParser(sStyle,"font-style",true);
  516. nodeElementLabelContainer.style.fontVariant= cssParser(sStyle,"font-variant",true);
  517. nodeElementLabelContainer.style.textAlign= cssParser(sStyle,"text-align",true);
  518. nodeElementLabelContainer.style.textVariant= cssParser(sStyle,"text-variant",true);
  519. nodeElementLabelContainer.style.textIndent= cssParser(sStyle,"text-indent",true);
  520. nodeElementLabelContainer.style.textTransform= cssParser(sStyle,"text-transform",true);
  521. nodeElementLabelContainer.setAttribute(gsCTREE_treeRef, treeRef);
  522. nodeElementLabelContainer.setAttribute(gsCTREE_dragRef, treeRef.toString());
  523. nodeElementLabelContainer.setAttribute(gsCTREE_dragTree, treeName);
  524. nodeElementLabelContainer.setAttribute(gsCTREE_tree, treeName);
  525. nodeElementLabelContainer.setAttribute("onfocus","this.classname='" + CLS_TREE_NODE_HOVER + " " + CLS_TREE_TEXT + "';");
  526. nodeElementLabelContainer.setAttribute("onblur","this.classname='" + CLS_TREE_NODE_UNSELECTED + " " + CLS_TREE_TEXT + "';");
  527. return nodeElementLabelContainer;
  528. };
  529. /**
  530. * Node structure
  531. * <div>
  532. * <nobr>
  533. * <img toogle>
  534. * [ checkbox ]
  535. * <span label>
  536. * [ indicator ]
  537. * <img icon>
  538. * <span labelText> </span>
  539. * </span>
  540. * </nobr>
  541. * </div>
  542. */
  543. CInnerTree.prototype.drawNode = function(node, nodeElement) {
  544. var treeRef = node.getTreeRef();
  545. var treeName = this.getName();
  546. nodeElement.className = CLS_TREE_LEVEL;
  547. nodeElement.setAttribute(gsCTREE_dragRef, treeRef.toString());
  548. nodeElement.setAttribute(gsCTREE_dragTree, treeName);
  549. nodeElement.setAttribute(K_PRMT_ARIA_ROLE, K_PRMT_ARIA_ROLE_PRESENTATION);
  550. // <nobr>
  551. var newNobr = this.m_oNOBR.cloneNode(true);
  552. //var newNobr = this.m_oDIVnewElement.cloneNode(true);
  553. newNobr.setAttribute(gsCTREE_treeRef, gsCTREE_nobr);
  554. newNobr.setAttribute(gsCTREE_tree, treeName);
  555. newNobr.setAttribute(K_PRMT_ARIA_ROLE, K_PRMT_ARIA_ROLE_PRESENTATION);
  556. newNobr.setAttribute("style", "white-space: nowrap;");
  557. nodeElement.appendChild(newNobr);
  558. this.drawTreeLines(node, newNobr, node.getLevel());
  559. // add [ indicator :<span><img></span> ]
  560. var nodeElementIndicator = null;
  561. if (node.getIndicator() != null)
  562. {
  563. nodeElementIndicator = createElementIndicator(node,treeName,treeRef);
  564. }
  565. // create <span label>
  566. var nodeElementText = this.m_oTextSPAN.cloneNode(true);
  567. nodeElementText.id = treeName + treeRef + gsCTREE_label;
  568. nodeElementText.setAttribute(gsCTREE_treeRef, treeRef);
  569. nodeElementText.setAttribute(gsCTREE_dragRef, treeRef.toString());
  570. nodeElementText.setAttribute(gsCTREE_dragTree, treeName);
  571. nodeElementText.setAttribute(gsCTREE_tree, treeName);
  572. nodeElementText.setAttribute(K_PRMT_ARIA_ROLE, K_PRMT_ARIA_ROLE_PRESENTATION);
  573. nodeElementText.title = (node.getTooltip() != false? node.getTooltip() : node.getName());
  574. if (G_IsBidiEnabled && this.m_sTextDir)
  575. {
  576. nodeElementText.title = PRMT_BidiUtils.enforceBidiDirection(nodeElementText.title, this.m_sTextDir);
  577. }
  578. // create node icon -> <img>
  579. var nodeElementIcon = this.m_oIcon.cloneNode(true);
  580. nodeElementIcon.id = treeName + treeRef + gsCTREE_icon;
  581. nodeElementIcon.setAttribute(gsCTREE_dragRef, treeRef.toString());
  582. nodeElementIcon.setAttribute(gsCTREE_dragTree, treeName);
  583. nodeElementIcon.setAttribute(K_PRMT_ARIA_ROLE, K_PRMT_ARIA_ROLE_PRESENTATION);
  584. nodeElementIcon.src = PROMT_IMAGES + "blank.gif"; //getIconSrc(node);
  585. nodeElementIcon.className = "clsTreeNodeIcon";
  586. nodeElementIcon.alt = "";
  587. nodeElementIcon.align = gsCTREE_middle;
  588. var newToggleIcon = null;
  589. if (node.getNodeType() == TREE_ROOT) {
  590. nodeElementText.onclick = function() {return false;};
  591. }
  592. else
  593. {
  594. var newToggleElems = this.drawToogleIcon(node);
  595. newToggleIcon = newToggleElems[0];
  596. newToggleIcon.id = treeName + treeRef + gsCTREE_toggle + node.getTreeHierarchy();
  597. newNobr.appendChild(newToggleIcon);
  598. newNobr.appendChild(newToggleElems[1]);
  599. if ((node.getTree().getForceSelectionAtLowestLevel() == true && node.getNodeType() == TREE_ITEM) || (node.getTree().getForceSelectionAtLowestLevel() == false))
  600. {
  601. nodeElementText.tabIndex = -1;
  602. PRMTUtils.f_addEvent(nodeElementText, "click", selectNode.bind(this));
  603. if (node.getTree().getSingleClickFunc() != null)
  604. {
  605. PRMTUtils.f_addEvent( nodeElementText, "click", singleClickCaller );
  606. }
  607. if (node.getTree().getDoubleClickFunc() != null)
  608. {
  609. PRMTUtils.f_addEvent( nodeElementText, "dblclick", doubleClickCaller );
  610. }
  611. nodeElementText.onmouseover = treeNodeMouseOver;
  612. nodeElementText.onmouseout = treeNodeMouseOut;
  613. PRMTUtils.f_addEvent( nodeElementText, "contextmenu", contextMenuCaller );
  614. }
  615. //add a checkbox for multiselect trees
  616. if (this.getSelectionMode() != SINGLE_TREE_SELECTION && this.getSelectTreeUI() == CHECKBOX_TREE)
  617. {
  618. var newCheckBoxIcon = this.drawNodeCheckboxIcon(node);
  619. newCheckBoxIcon.id = treeName + treeRef + gsCTREE_checkbox;
  620. newCheckBoxIcon.firstChild.id = treeName + treeRef + gsCTREE_checkbox + "Input";
  621. newNobr.appendChild(newCheckBoxIcon);
  622. }
  623. }
  624. // add icon
  625. nodeElementText.appendChild(nodeElementIcon);
  626. // add the indicator if there is one
  627. if (nodeElementIndicator != null)
  628. {
  629. nodeElementText.appendChild(nodeElementIndicator);
  630. }
  631. // <span labeltext
  632. var nodeElementLabelContainer = this.drawNodeLabel(node, treeName, treeRef);
  633. if (newToggleIcon != null)
  634. {
  635. if (newToggleIcon.title == PMT_TRE_COLLAPSE)
  636. {
  637. nodeElementLabelContainer.setAttribute(K_PRMT_TREE_STATE_EXPANDED, true);
  638. }
  639. else
  640. {
  641. nodeElementLabelContainer.setAttribute(K_PRMT_TREE_STATE_EXPANDED, false);
  642. }
  643. }
  644. nodeElementText.appendChild(nodeElementLabelContainer);
  645. newNobr.appendChild(nodeElementText);
  646. PRMTUtils.f_addEvent(nodeElementText, "keydown", this.f_treeEventHandler.bind(this) );
  647. if (node.isOpen())
  648. {
  649. node.setRendered(true);
  650. }
  651. };
  652. CInnerTree.prototype.getExpandedNodeCacheKey = function(node)
  653. {
  654. return node.getValue() + "_expanded";
  655. };
  656. //update selections
  657. //loop through the tree recursively to paint selections
  658. CInnerTree.prototype.drawNodeChildren = function (node, nodeElement)
  659. {
  660. if (node.hasChildren() == true)
  661. {
  662. if (node.isOpen() == true)
  663. {
  664. //get any children
  665. var children = node.getChildren();
  666. var parent = node.getParent();
  667. // make sure setSelected is run only once, since it traverses through all the child nodes.
  668. if (node.isSelected() == true && parent != null && parent.isSelected() == false)
  669. {
  670. node.setSelected(true);
  671. }
  672. //move recursively and render all children
  673. for (var iChildCounter = 0; iChildCounter < children.length; iChildCounter++)
  674. {
  675. this.draw(children[iChildCounter], nodeElement);
  676. }
  677. }
  678. else
  679. {
  680. var unopenedSelectedChildren = this.hasUnopenedSelectedChild(node);
  681. if ((node.isSelected() == false) && unopenedSelectedChildren == true)
  682. {
  683. node.setHasSelectedChildren(true);
  684. node.updateNodeSelection();
  685. }
  686. if (node.hasSelectedChildren() == true || unopenedSelectedChildren == true)
  687. {
  688. if (this.getSelectionMode() == CONTIGUOUS_TREE_SELECTION) {
  689. node.updateParent();
  690. }
  691. else {
  692. node.partialSelectParent();
  693. }
  694. }
  695. }
  696. }
  697. else
  698. {
  699. if ((node.getNodeType() == TREE_ROOT) && ((node.getTree().getPromptingTree() != false) || (node.getTree().getLoadOnTheFly() != false)))
  700. {
  701. node.setRendered(false);
  702. node.fetchChildren();
  703. }
  704. else if ((node.isSelected() == true))
  705. {
  706. if (this.getSelectionMode() == CONTIGUOUS_TREE_SELECTION) {
  707. node.updateParent();
  708. }
  709. else {
  710. node.partialSelectParent();
  711. }
  712. }
  713. // check if the node was expanded. We do this in a timeout to make
  714. // sure that the tree has finished rendering.
  715. var _self = this;
  716. var checkExpandedState = function()
  717. {
  718. var isExpanded = (_self.getCacheValue(_self.getExpandedNodeCacheKey(node)) == "true");
  719. if (isExpanded)
  720. {
  721. _self.toggleExpandCollapse(nodeElement, node, K_PRMT_TREE_EXPAND);
  722. }
  723. };
  724. window.setTimeout(checkExpandedState, 0);
  725. }
  726. };
  727. /*
  728. * handle tree keyboard navigation
  729. */
  730. CInnerTree.prototype.f_treeEventHandler = function (evt)
  731. {
  732. evt = ( arguments && arguments.length ? arguments[arguments.length-1] : null );
  733. var v_oEvt = (evt ? evt : (typeof event != K_PRMT_sUNDEFINED ? event : null ));
  734. if ( v_oEvt == null )
  735. {
  736. return false;
  737. }
  738. var result = false;
  739. if ( v_oEvt )
  740. {
  741. //cancel any text selection
  742. clearSelection();
  743. var v_nodeInfo = getTargetNodeInfo(evt);
  744. var toogleDirection = 0;
  745. var focusDelta = 0;
  746. if ( v_oEvt.type == "keydown" ) {
  747. var keyCode = (v_oEvt.keyCode? v_oEvt.keyCode : v_oEvt.which);
  748. if (v_oEvt.altKey || keyCode == 9) {
  749. return true; // Browser should use this, the tree view does not need alt-modified keys or the TAB key
  750. }
  751. switch (keyCode)
  752. {
  753. case K_KEY_LEFT:
  754. toogleDirection = K_PRMT_TREE_COLLAPSE;
  755. break;
  756. case K_KEY_RIGHT:
  757. toogleDirection = K_PRMT_TREE_EXPAND;
  758. break;
  759. case K_KEY_UP:
  760. focusDelta = K_PRMT_TREE_MOVE_UP;
  761. break;
  762. case K_KEY_DOWN:
  763. focusDelta = K_PRMT_TREE_MOVE_DOWN;
  764. break;
  765. case K_KEY_SPACE:
  766. this.processNodeSelection(v_nodeInfo.node, v_nodeInfo.uiNode.getAttribute(gsCTREE_tree).toString(), v_oEvt.ctrlKey, v_oEvt.shiftKey);
  767. break;
  768. default:
  769. return selectNode(evt);
  770. }
  771. }
  772. if ( toogleDirection != 0 )
  773. {
  774. if ( !this.toggleExpandCollapse(v_nodeInfo.uiNode, v_nodeInfo.node, toogleDirection) ) {
  775. focusDelta = toogleDirection * 2;
  776. }
  777. }
  778. if ( focusDelta != 0 )
  779. {
  780. var nextNode = this.f_getRelativeTreeItem(focusDelta, v_nodeInfo.node);
  781. if (nextNode != null && nextNode != v_nodeInfo.node)
  782. {
  783. this.f_moveFocus( v_nodeInfo.node, nextNode);
  784. }
  785. }
  786. PRMTUtils.F_StopEvent(evt);
  787. }
  788. return result;
  789. };
  790. /**
  791. * find the relative tree item
  792. */
  793. CInnerTree.prototype.f_getRelativeTreeItem = function (delta, node)
  794. {
  795. var result = null;
  796. var parentNode = node.getParent();
  797. if ( delta == K_PRMT_TREE_MOVE_DOWN ) { // Next
  798. if (node.isClosed() || !node.hasChildren()) {
  799. if ( node.isLastSibling() && parentNode != null ) {
  800. if ( parentNode.getMoreData() == true )
  801. {
  802. // move the focus to the More node
  803. if (this.f_moveFocusToMoreDataNode(parentNode))
  804. {
  805. // return null to avoid the execution of this.f_moveFocus in the caller function
  806. return null;
  807. }
  808. }
  809. while ( parentNode != node.getRootNode() ) {
  810. if ( parentNode.getNextSibling() != null ) {
  811. result = parentNode.getNextSibling();
  812. break;
  813. } else {
  814. parentNode = parentNode.getParent();
  815. }
  816. }
  817. } else {
  818. result = node.getNextSibling();
  819. }
  820. } else if ( node.isOpen() ) { //open
  821. result = node.getFirstChild();
  822. }
  823. }
  824. else if ( delta == K_PRMT_TREE_MOVE_UP )//Prev
  825. {
  826. if ( !node.isFirstSibling() ) {
  827. result = node.getPreviousSibling();
  828. // find the last visible leaf
  829. while ( result && result.hasChildren() && result.isOpen() )
  830. {
  831. result = result.getLastChild();
  832. }
  833. } else {
  834. if ( parentNode != node.getRootNode() ) {
  835. result = parentNode;
  836. }
  837. }
  838. }
  839. else if ( delta == K_PRMT_TREE_MOVE_PARENT_LEVEL ) //Prev level
  840. {
  841. if ( parentNode != node.getRootNode() ) {
  842. result = parentNode;
  843. }
  844. }
  845. else if ( delta == K_PRMT_TREE_MOVE_CHILD_LEVEL ) //Next level
  846. {
  847. if ( node.isOpen() && node.hasChildren() ) {
  848. result = node.getFirstChild();
  849. }
  850. }
  851. return result;
  852. };
  853. /**
  854. * Move the focus to the More data node
  855. */
  856. CInnerTree.prototype.f_moveFocusToMoreDataNode = function (parentNode)
  857. {
  858. // get the node holding the More data label
  859. var moreDataSpan = document.getElementById(parentNode.getTree().getName() + parentNode.getTreeRef() + 'moredatalabel');
  860. if ( moreDataSpan != null )
  861. {
  862. this.m_lastFocus.tabIndex = -1;
  863. this.m_lastFocus = moreDataSpan;
  864. this.m_lastFocus.tabIndex = 0;
  865. window.setTimeout(function () { moreDataSpan.focus(); },0);
  866. return true;
  867. }
  868. return false;
  869. }
  870. /**
  871. * Move the focus to the next node if possible
  872. */
  873. CInnerTree.prototype.f_moveFocus = function (node, nextNode)
  874. {
  875. try {
  876. var treeName = this.getName();
  877. this.m_lastFocus.tabIndex = -1;
  878. if(node == null) {
  879. node = getUINodeNodeInfo(this.m_lastFocus).node;
  880. }
  881. // this.m_lastFocus.className = getClassName(node, this);
  882. this.updateLabelClass(this.m_lastFocus, getClassName(node, this), node);
  883. var labelSpan = nextNode.getLabelContainer(treeName);
  884. this.m_lastFocus = labelSpan;
  885. // this.m_lastFocus.className = CLS_TREE_NODE_HOVER + " " + CLS_TREE_TEXT;
  886. this.updateLabelClass(this.m_lastFocus, CLS_TREE_NODE_HOVER, nextNode);
  887. this.m_lastFocus.tabIndex = 0;
  888. window.setTimeout(function () { labelSpan.focus(); },0);
  889. } catch(e) {}
  890. };
  891. //update selections
  892. //loop through the tree recursively to paint selections
  893. CInnerTree.prototype.getFirstTreeNode = function ()
  894. {
  895. var v_result = null;
  896. var v_rootNode = this.getRootNode();
  897. if ( (rootNode.m_sId != node.m_sId) && (rootNode.hasChildren()) )
  898. {
  899. v_result = rootNode.getChildren()[0];
  900. }
  901. return result;
  902. };
  903. // hide|show children nodes by setting css display attr of the children container to the proper value: "block" or "none"
  904. CInnerTree.prototype.setNodeChildrenDisplay = function( uiNode, displayValue )
  905. {
  906. var childrenContainer = uiNode.firstChild.nextSibling;
  907. if (childrenContainer && childrenContainer.getAttribute("role") == "group")
  908. {
  909. childrenContainer.style.display = displayValue;
  910. }
  911. };
  912. CInnerTree.prototype.closeUINode = function( uiNode )
  913. {
  914. this.setNodeChildrenDisplay(uiNode, "none");
  915. };
  916. CInnerTree.prototype.openUINode = function( uiNode )
  917. {
  918. this.setNodeChildrenDisplay(uiNode, "block");
  919. };
  920. function expandFolderChildren(uiNode, node)
  921. {
  922. if (node.hasChildren())
  923. {
  924. //draw the nodes if they haven't been rendered
  925. if (node.getRendered() == false)
  926. {
  927. var tree = uiNode.getAttribute(gsCTREE_tree).toString();
  928. gDrawChildren(node, uiNode,
  929. function() {
  930. node.setRendered(true);
  931. node.setOpen(true);
  932. updateToggleIcon(node, tree);
  933. }
  934. );
  935. return;
  936. }
  937. }
  938. else
  939. {
  940. if (node.fetchChildren() == false) {
  941. return false;
  942. }
  943. }
  944. }
  945. CInnerTree.prototype.expandNode = function (uiNode, node)
  946. {
  947. if (((node.getTree().getPromptingTree() != false) && (typeof activeFetchingTreeNode == K_PRMT_sUNDEFINED || activeFetchingTreeNode == null)) || (typeof node.getTree().getLoadOnTheFly() == K_PRMT_sFUNCTION))
  948. {
  949. this.openUINode(uiNode);
  950. expandFolderChildren(uiNode, node);
  951. }
  952. else
  953. {
  954. this.openUINode(uiNode);
  955. //draw the nodes if they haven't been rendered
  956. if (node.getRendered() == false)
  957. {
  958. var children = node.getChildren();
  959. var j = 0;
  960. for (j = 0; j < children.length; j ++)
  961. {
  962. node.getTree().draw (children[j], uiNode);
  963. }
  964. node.setRendered(true);
  965. }
  966. }
  967. node.setOpen(true);
  968. };
  969. CInnerTree.prototype.collapseNode = function(uiNode, node)
  970. {
  971. this.closeUINode(uiNode);
  972. node.setOpen(false);
  973. };
  974. // check if node can be toggled
  975. CInnerTree.prototype.canToggleNode = function(node)
  976. {
  977. var v_bResult = ((
  978. (
  979. (node.getTree().getPromptingTree() != false) &&
  980. (typeof activeFetchingTreeNode == K_PRMT_sUNDEFINED || activeFetchingTreeNode == null)
  981. ) ||
  982. (typeof node.getTree().getLoadOnTheFly() == K_PRMT_sFUNCTION)
  983. ) ? true : false);
  984. return v_bResult;
  985. };
  986. /**
  987. * Process event from click in Toggle icon
  988. */
  989. function toggle(evt, uiNode)
  990. {
  991. //get the event in a cross-browser fashion
  992. evt = (evt) ? evt : ((event) ? event : null);
  993. //cancel any text selection
  994. clearSelection();
  995. //prevent the event from bubbling to other elements
  996. PRMTUtils.F_StopEvent(evt);
  997. //get UI Node
  998. uiNode = (uiNode? getUINode(null, uiNode) : getUINode(evt));
  999. var uiNodeTreeRef = uiNode.getAttribute(gsCTREE_treeRef).toString();
  1000. //get the tree object
  1001. var tree = uiNode.getAttribute(gsCTREE_tree).toString();
  1002. //get tree Node
  1003. var node = getTreeNode(tree, uiNodeTreeRef);
  1004. var v_oTree = node.getTree();
  1005. if (v_oTree && v_oTree.canToggleNode(node))
  1006. {
  1007. v_oTree.toggleExpandCollapse(uiNode, node, 0);
  1008. v_oTree.f_moveFocus(null, node);
  1009. }
  1010. }
  1011. CInnerTree.prototype.toggleExpandCollapse = function(uiNode, node, toggleDirection)
  1012. {
  1013. var result = false;
  1014. var tree = uiNode.getAttribute(gsCTREE_tree).toString();
  1015. //toggle folders
  1016. var isExpanded = null;
  1017. if ( node.isClosed() && toggleDirection != K_PRMT_TREE_COLLAPSE )
  1018. {
  1019. isExpanded = true;
  1020. this.expandNode(uiNode, node);
  1021. result = true;
  1022. }
  1023. else if ( (node.isOpen()) && toggleDirection != K_PRMT_TREE_EXPAND )
  1024. {
  1025. isExpanded = false;
  1026. this.collapseNode(uiNode, node);
  1027. result = true;
  1028. }
  1029. if (isExpanded){
  1030. this.setCacheValue(this.getExpandedNodeCacheKey(node), "true");
  1031. }else{
  1032. this.removeCacheValue(this.getExpandedNodeCacheKey(node));
  1033. }
  1034. updateToggleIcon(node, tree);
  1035. // update aria-expanded
  1036. if ( isExpanded != null ) {
  1037. this.updateAriaLabelContainer(node, tree, isExpanded);
  1038. }
  1039. return result;
  1040. };
  1041. function gDrawChildren(oNode, oParentUI, oFctWhenComplete, iStart)
  1042. {
  1043. var aChildren = oNode.getChildren();
  1044. var oTree = oNode.getTree();
  1045. if (!iStart) {
  1046. iStart = 0;
  1047. }
  1048. var iMax = Math.min((iStart + giDRAW_BLOCKSIZE), aChildren.length);
  1049. var idxChild = iStart;
  1050. var childrenContainerId = oTree.getName() + oNode.getTreeRef() + "children";
  1051. var childrenContainer = document.getElementById(childrenContainerId);
  1052. if (!childrenContainer) {
  1053. childrenContainer = oTree.m_oDIVGroupElement.cloneNode(true);
  1054. childrenContainer.id = childrenContainerId;
  1055. oParentUI.appendChild(childrenContainer);
  1056. }
  1057. for (idxChild = iStart; idxChild < iMax; idxChild++)
  1058. {
  1059. oTree.draw(aChildren[idxChild], childrenContainer);
  1060. }
  1061. if (idxChild < aChildren.length)
  1062. {
  1063. setTimeout(
  1064. function () {
  1065. gDrawChildren(oNode, oParentUI, oFctWhenComplete, idxChild);
  1066. },
  1067. giDRAW_INTERVAL );
  1068. }
  1069. else if (typeof oFctWhenComplete == K_PRMT_sFUNCTION)
  1070. {
  1071. oFctWhenComplete();
  1072. }
  1073. }
  1074. /**
  1075. * Update the label container<span> aria-expanded attribute
  1076. */
  1077. CInnerTree.prototype.updateAriaLabelContainer = function(oNode, sTreeName, ariaExpanded)
  1078. {
  1079. var labelContainer = document.getElementById(sTreeName + oNode.getTreeRef() + gsCTREE_labelText);
  1080. if (labelContainer)
  1081. {
  1082. labelContainer.setAttribute(K_PRMT_TREE_STATE_EXPANDED, ariaExpanded);
  1083. }
  1084. };
  1085. CInnerTree.prototype.updateLabelClass = function(labelElem, className, node)
  1086. {
  1087. labelElem.className = className + " " + CLS_TREE_TEXT;
  1088. // update aria-ckecked for the single selection tree, for multiple selection is done in the updateCheckbox function
  1089. if (!(this.getSelectionMode() != SINGLE_TREE_SELECTION && this.getSelectTreeUI() == CHECKBOX_TREE) && node) {
  1090. updateLabelAriaChecked(labelElem, node)
  1091. }
  1092. };
  1093. /*
  1094. * override cancelBub => PRMTUtils.F_StopEvent to avoid duplication of
  1095. * several functions which only difference is using cancelBub instead of
  1096. * PRMTUtils.F_StopEvent
  1097. */
  1098. function cancelBub(evt)
  1099. {
  1100. return PRMTUtils.F_StopEvent.apply(this, arguments);
  1101. }
  1102. // get the UINode and TreeNode which are the event target
  1103. function getTargetNodeInfo(evt)
  1104. {
  1105. return getUINodeNodeInfo(getUINode(evt));
  1106. }
  1107. function getUINodeNodeInfo(uiNode)
  1108. {
  1109. var result = {};
  1110. result.uiNode = uiNode;
  1111. var uiNodeTreeRef = uiNode.getAttribute(gsCTREE_treeRef).toString();
  1112. //get the tree id
  1113. result.tree = uiNode.getAttribute(gsCTREE_tree).toString();
  1114. //get tree Node
  1115. result.node = getTreeNode(result.tree, uiNodeTreeRef);
  1116. return result;
  1117. }
  1118. function selectNode(evt)
  1119. {
  1120. //get the event in a cross-browser fashion
  1121. evt = (evt) ? evt : ((event) ? event : null);
  1122. if ((evt != null) && (evt.keyCode != null) && (evt.keyCode != 13) && (evt.keyCode != 0))
  1123. {
  1124. return false;
  1125. }
  1126. //cancel any text selection
  1127. clearSelection();
  1128. //prevent the event from bubbling to other elements
  1129. PRMTUtils.F_StopEvent(evt);
  1130. //get UI Node
  1131. var uiNode = getUINode(evt);
  1132. var uiNodeTreeRef = uiNode.getAttribute(gsCTREE_treeRef).toString();
  1133. //get the tree object
  1134. var tree = uiNode.getAttribute(gsCTREE_tree).toString();
  1135. //get tree Node
  1136. var node = getTreeNode(tree, uiNodeTreeRef);
  1137. var oTree = node.getTree();
  1138. oTree.f_moveFocus(null, node);
  1139. oTree.processNodeSelection(node, tree, evt.ctrlKey, evt.shiftKey);
  1140. if (oTree.m_oTreeControl)
  1141. {
  1142. oTree.m_oTreeControl.cacheControlValue();
  1143. }
  1144. return false;
  1145. }
  1146. /**
  1147. * Process node selection, is called by click and keydown(SPACE) event handlers
  1148. *
  1149. */
  1150. CInnerTree.prototype.processNodeSelection = function(node, tree, ctrlKey, shiftKey) {
  1151. //handle multiple select
  1152. if (this.getSelectionMode() != SINGLE_TREE_SELECTION)
  1153. {
  1154. if ((ctrlKey == false) && (shiftKey == false) && (this.getSelectTreeUI() != CHECKBOX_TREE))
  1155. {
  1156. this.clearPreviousSelections();
  1157. }
  1158. var normalTreeNeedsRedraw = ((this.getSelectTreeUI() == NORMAL_TREE) && (ctrlKey == false) && (shiftKey == false));
  1159. var unselectNode = ((this.getSelectTreeUI() == CHECKBOX_TREE) || ((this.getSelectTreeUI() == NORMAL_TREE) && ((this.getAllowSelectionToggle() == true) || ((this.getAllowSelectionToggle() == false) && (ctrlKey == true)))));
  1160. if (normalTreeNeedsRedraw)
  1161. {
  1162. this.getRootNode().setSelected(false);
  1163. if (this.getTrackSelectionOrder())
  1164. {
  1165. this.clearSelectionOrder();
  1166. }
  1167. }
  1168. //setSelected
  1169. var nodeWasSelected = node.isSelected();
  1170. if ((this.getSelectTreeUI() == NORMAL_TREE) && (shiftKey == true))
  1171. {
  1172. var anchorNode = this.getAnchorNode();
  1173. if (anchorNode != null && node.getRootNode().hasSelectedChildren())
  1174. {
  1175. if (node.getParent() == anchorNode.getParent())
  1176. {
  1177. var anchorNodeIndex = anchorNode.getIndex();
  1178. var nodeIndex = node.getIndex();
  1179. var iCurrentNode = anchorNodeIndex;
  1180. var iIncrement = ((anchorNodeIndex > nodeIndex)? - 1 : 1);
  1181. //select all of the children between the anchor node and the selected node
  1182. while (iCurrentNode != nodeIndex + iIncrement)
  1183. {
  1184. var siblingNode = node.getParent().m_oChildren[iCurrentNode];
  1185. siblingNode.setSelected(true);
  1186. var oLabel = siblingNode.getLabel(tree);
  1187. this.updateLabelClass(oLabel, getClassName(siblingNode, this), siblingNode);
  1188. redrawChildren(siblingNode, tree);
  1189. iCurrentNode += iIncrement;
  1190. }
  1191. }
  1192. }
  1193. }
  1194. if (nodeWasSelected == true)
  1195. {
  1196. if (unselectNode)
  1197. {
  1198. node.setSelected(false);
  1199. this.setLastSelectedNode(null);
  1200. this.removeFromPrevSelArray( node.getValue(), node.getName() );
  1201. }
  1202. }
  1203. else
  1204. {
  1205. node.setSelected(true);
  1206. this.setLastSelectedNode(node);
  1207. }
  1208. node.updateNodeSelection();
  1209. node.updateParent();
  1210. this.updateLabelClass(node.getLabel(tree), getClassName(node, this), node);
  1211. this.checkData();
  1212. if (normalTreeNeedsRedraw)
  1213. {
  1214. this.redraw();
  1215. this.checkData();
  1216. }
  1217. else
  1218. {
  1219. redrawChildren(node, tree);
  1220. redrawParents(node, tree);
  1221. }
  1222. if (unselectNode && nodeWasSelected)
  1223. {
  1224. this.setAnchorNode(null);
  1225. }
  1226. else
  1227. {
  1228. this.setAnchorNode(node);
  1229. }
  1230. }
  1231. else
  1232. {
  1233. //single select remove all other selections
  1234. this.clearPreviousSelections();
  1235. if (node.isSelected() == true && this.getAllowSelectionToggle() == true)
  1236. {
  1237. this.getRootNode().setSelected(false);
  1238. this.setLastSelectedNode(null);
  1239. }
  1240. else
  1241. {
  1242. this.getRootNode().setSelected(false);
  1243. node.setSelected(true);
  1244. this.setLastSelectedNode(node);
  1245. }
  1246. node.updateParent();
  1247. this.redraw();
  1248. this.checkData();
  1249. }
  1250. };
  1251. function redrawChildren(node,tree)
  1252. {
  1253. //has the child node been rendered?
  1254. //draw the nodes if they haven't been rendered
  1255. if (node.getRendered() == true)
  1256. {
  1257. var children = node.getChildren();
  1258. var oTree = node.getTree();
  1259. var childrenContainer = document.getElementById(tree + node.getTreeRef() + "children");
  1260. // when redrawing first level (by selecting "More") the container Id has not the "children" suffix
  1261. if (childrenContainer === null) {
  1262. childrenContainer = document.getElementById(tree + node.getTreeRef());
  1263. }
  1264. for (var j = 0; j < children.length; j++)
  1265. {
  1266. var oChild = children[j];
  1267. var labelElem = oChild.getLabel(tree);
  1268. if (labelElem == null)
  1269. {
  1270. if (j > 0)
  1271. {
  1272. oTree.redrawNodeToggle(children[j - 1], tree + children[j - 1].getTreeRef());
  1273. }
  1274. oTree.draw(oChild, childrenContainer);
  1275. if (node.isOpen() == false)
  1276. {
  1277. document.getElementById(tree + oChild.getTreeRef()).style.display = "none";
  1278. }
  1279. }
  1280. else
  1281. {
  1282. oTree.updateLabelClass(labelElem, getClassName(oChild, oTree), oChild);
  1283. if (oTree.getSelectionMode() != SINGLE_TREE_SELECTION)
  1284. {
  1285. if (oTree.getSelectTreeUI() == CHECKBOX_TREE)
  1286. {
  1287. var checkbox = oChild.getCheckbox(tree);
  1288. if (checkbox) {
  1289. updateCheckboxClass(checkbox, oChild);
  1290. }
  1291. }
  1292. }
  1293. }
  1294. redrawChildren(oChild,tree);
  1295. }
  1296. }
  1297. }
  1298. function redrawParents(node, tree)
  1299. {
  1300. var parentNode = node.getParent();
  1301. if (parentNode != null)
  1302. {
  1303. var labelElem = parentNode.getLabel(tree);
  1304. if (labelElem != null)
  1305. {
  1306. var v_oTree = parentNode.getTree();
  1307. v_oTree.updateLabelClass(labelElem, getClassName(parentNode, v_oTree), parentNode);
  1308. if (node.getTree().getSelectionMode() != SINGLE_TREE_SELECTION)
  1309. {
  1310. if (parentNode.getTreeRef() != null && parentNode.getTreeRef().length != 0)
  1311. {
  1312. if (node.getTree().getSelectTreeUI() == CHECKBOX_TREE)
  1313. {
  1314. var checkbox = parentNode.getCheckbox(tree);
  1315. updateCheckboxClass(checkbox, parentNode);
  1316. }
  1317. redrawParents(parentNode, tree);
  1318. }
  1319. }
  1320. }
  1321. }
  1322. }
  1323. function dragStartOnNode(evt)
  1324. {
  1325. //get the event in a cross-browser fashion
  1326. evt = (evt) ? evt : ((event) ? event : null);
  1327. //cancel any text selection
  1328. clearSelection();
  1329. //prevent the event from bubbling to other elements
  1330. PRMTUtils.F_StopEvent(evt);
  1331. var dragRef = evt.srcElement.getAttribute(gsCTREE_dragRef);
  1332. if (typeof dragRef == K_PRMT_sSTRING && dragRef.length != 0)
  1333. {
  1334. var uiNode = getUINode(evt);
  1335. if (uiNode)
  1336. {
  1337. //get the tree object
  1338. var tree = uiNode.getAttribute(gsCTREE_dragTree).toString();
  1339. //get tree Node
  1340. var node = getTreeNode(tree, dragRef);
  1341. var treeObj = node.getTree();
  1342. if (!node.isSelected())
  1343. {
  1344. if ((evt.ctrlKey == false) && (evt.shiftKey == false))
  1345. {
  1346. treeObj.getRootNode().setSelected(false);
  1347. treeObj.clearPreviousSelections();
  1348. if (treeObj.getTrackSelectionOrder())
  1349. {
  1350. treeObj.clearSelectionOrder();
  1351. }
  1352. }
  1353. //select all the children
  1354. node.setSelected(true);
  1355. //update the parent
  1356. node.updateParent();
  1357. treeObj.updateLabelClass(node.getLabel(), getClassName(node, treeObj). node);
  1358. if ((evt.ctrlKey == false) && (evt.shiftKey == false))
  1359. {
  1360. treeObj.redraw();
  1361. treeObj.checkData();
  1362. }
  1363. }
  1364. var selectedNodes = treeObj.getSelectedFolderNodes();
  1365. selectedNodes = selectedNodes.concat(treeObj.getSelectedLeafNodes());
  1366. var selNodesStr = tree + "~~~~~";
  1367. for (var i = 0; i < selectedNodes.length; i++)
  1368. {
  1369. if (i > 0)
  1370. {
  1371. selNodesStr += "~~~";
  1372. }
  1373. selNodesStr += selectedNodes[i].getTreeRef();
  1374. }
  1375. event.dataTransfer.setData("Text", selNodesStr);
  1376. if (treeObj.getOnDragStart() != null)
  1377. {
  1378. var dragStartFunction = treeObj.getOnDragStart();
  1379. dragStartFunction(evt);
  1380. }
  1381. }
  1382. }
  1383. }
  1384. /////////////////////
  1385. //utility functions
  1386. /**
  1387. * find the DIV enclosing element for the node where the event occurred
  1388. */
  1389. function getUINode (evt, uiNode)
  1390. {
  1391. if (!uiNode)
  1392. {
  1393. //get the element that trapped the event in a cross-browser fashion
  1394. uiNode = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement : null);
  1395. }
  1396. while ( uiNode && !(uiNode.tagName == "DIV" && uiNode.getAttribute(gsCTREE_tree) != null) )
  1397. {
  1398. uiNode = uiNode.parentNode;
  1399. }
  1400. return uiNode;
  1401. }
  1402. //return plus or minus icons for the given node
  1403. function getToggleSrc(node)
  1404. {
  1405. if (node.isOpen() == true)
  1406. {
  1407. if (node.isLastSibling() == true && node.getParent().getMoreData() != true)
  1408. {
  1409. return TREE_L_MINUS;
  1410. }
  1411. else
  1412. {
  1413. return TREE_T_MINUS;
  1414. }
  1415. }
  1416. else
  1417. {
  1418. if (node.isLastSibling() == true && node.getParent().getMoreData() != true)
  1419. {
  1420. return TREE_L_PLUS;
  1421. }
  1422. else
  1423. {
  1424. return TREE_T_PLUS;
  1425. }
  1426. }
  1427. }
  1428. function treeNodeMouseOver(evt)
  1429. {
  1430. //get the event in a cross-browser fashion
  1431. evt = (evt) ? evt : ((event) ? event : null);
  1432. //cancel any text selection
  1433. clearSelection();
  1434. //prevent the event from bubbling to other elements
  1435. PRMTUtils.F_StopEvent(evt);
  1436. //get UI Node
  1437. var uiNode = getUINode(evt);
  1438. var uiNodeTreeRef = uiNode.getAttribute(gsCTREE_treeRef).toString();
  1439. //get the tree object
  1440. var tree = uiNode.getAttribute(gsCTREE_tree).toString();
  1441. //get tree Node
  1442. var node = getTreeNode(tree, uiNodeTreeRef);
  1443. window.status = K_PRMT_sEMPTY;
  1444. var v_oTree = node.getTree();
  1445. if (v_oTree) v_oTree.treeNodeShowFocus(node, tree);
  1446. }
  1447. CInnerTree.prototype.treeNodeShowFocus = function(node, tree)
  1448. {
  1449. if (node.getNodeTypeObject().getSelectable() && node.isSelected() == false && node.hasSelectedChildren() == false)
  1450. {
  1451. this.updateLabelClass(node.getLabel(tree), CLS_TREE_NODE_HOVER, node);
  1452. }
  1453. };
  1454. CInnerTree.prototype.treeNodeHideFocus = function(node, tree)
  1455. {
  1456. if (node.isSelected() == false && node.hasSelectedChildren() == false)
  1457. {
  1458. this.updateLabelClass(node.getLabel(tree), CLS_TREE_NODE_UNSELECTED, node);
  1459. }
  1460. };
  1461. function treeNodeMouseOut(evt)
  1462. {
  1463. //get the event in a cross-browser fashion
  1464. evt = (evt) ? evt : ((event) ? event : null);
  1465. //cancel any text selection
  1466. clearSelection();
  1467. //prevent the event from bubbling to other elements
  1468. PRMTUtils.F_StopEvent(evt);
  1469. //get UI Node
  1470. var uiNode = getUINode(evt);
  1471. var uiNodeTreeRef = uiNode.getAttribute(gsCTREE_treeRef).toString();
  1472. //get the tree object
  1473. var tree = uiNode.getAttribute(gsCTREE_tree).toString();
  1474. //get tree Node
  1475. var node = getTreeNode(tree, uiNodeTreeRef);
  1476. window.status = K_PRMT_sEMPTY;
  1477. var v_oTree = node.getTree();
  1478. if (v_oTree) v_oTree.treeNodeHideFocus(node, tree);
  1479. }
  1480. /////////////////////////////////
  1481. // Tree node object
  1482. // oParentTreeNode: the parent node - null for the root node
  1483. // oTreeNodeType: the type of node, a TreeNodeType object (e.g. folder/leaf)
  1484. // bOpenState: if this is a container, whether the the default state is open or closed [true|false]
  1485. // name: the display value for the tree node
  1486. // value: the use value for the tree node
  1487. // bSelected: whether this node has been selected or not
  1488. //Tree nodes
  1489. function CInnerTreeNode(oParentTreeNode, oTreeNodeType, bOpenState, sName, value, bSelected)
  1490. {
  1491. if (oTreeNodeType)
  1492. {
  1493. this.init(oParentTreeNode, oTreeNodeType, bOpenState, sName, value, bSelected);
  1494. }
  1495. }
  1496. CInnerTreeNode.prototype = new CTreeNode();
  1497. CInnerTreeNode.prototype.isFirst = function ()
  1498. {
  1499. var v_bResult = false;
  1500. if ((this.getParent() != null) && (this.getParent() == this.getRootNode()) && (this.getTreeRef() == this.getParent().m_oChildren[0].getTreeRef()))
  1501. {
  1502. v_bResult = true;
  1503. }
  1504. return v_bResult;
  1505. };
  1506. CInnerTreeNode.prototype.isFirstSibling = function ()
  1507. {
  1508. var v_bResult = false;
  1509. if ((this.getParent() != null) && (this.getTreeRef() == this.getParent().m_oChildren[0].getTreeRef()))
  1510. {
  1511. v_bResult = true;
  1512. }
  1513. return v_bResult;
  1514. };
  1515. CInnerTreeNode.prototype.isLastSibling = function ()
  1516. {
  1517. var v_bResult = false;
  1518. if ((this.getParent() != null) && (this.getTreeRef() == this.getParent().m_oChildren[this.getParent().getChildrenLength() - 1].getTreeRef()))
  1519. {
  1520. v_bResult = true;
  1521. }
  1522. return v_bResult;
  1523. };
  1524. CInnerTreeNode.prototype.getNextSibling = function ()
  1525. {
  1526. var v_oResult = null;
  1527. if (! this.isLastSibling())
  1528. {
  1529. v_oResult = this.getParent().m_oChildren[this.getIndex() + 1];
  1530. }
  1531. return v_oResult;
  1532. };
  1533. CInnerTreeNode.prototype.getPreviousSibling = function ()
  1534. {
  1535. var v_oResult = null;
  1536. if (! this.isFirstSibling())
  1537. {
  1538. v_oResult = this.getParent().m_oChildren[this.getIndex() - 1];
  1539. }
  1540. return v_oResult;
  1541. };
  1542. CInnerTreeNode.prototype.getLabel = function (sTreeRef)
  1543. {
  1544. if (!this.m_oLabelText) {
  1545. this.m_oLabelText = document.getElementById(sTreeRef + this.getTreeRef() + gsCTREE_labelText);
  1546. }
  1547. return this.m_oLabelText;
  1548. };
  1549. CInnerTreeNode.prototype.getLabelContainer = function (treeName)
  1550. {
  1551. return document.getElementById(treeName + this.getTreeRef() + gsCTREE_labelText);
  1552. };
  1553. CInnerTreeNode.prototype.getNodeLabel = function ()
  1554. {
  1555. var v_oTree = this.getTree();
  1556. var v_sTreeRef = v_oTree.getName();
  1557. if (!this.m_oLabelText) {
  1558. this.m_oLabelText = document.getElementById(sTreeRef + this.getTreeRef() + gsCTREE_labelText);
  1559. }
  1560. return this.m_oLabelText;
  1561. };
  1562. //boolean: returns whether the node has children or not
  1563. CInnerTreeNode.prototype.hasChildren = function ()
  1564. {
  1565. return(this.getChildrenLength() > 0);
  1566. };
  1567. CInnerTreeNode.prototype.updateNodeSelection = function ()
  1568. {
  1569. var v_oTree = this.getTree();
  1570. if (v_oTree.getSelectTreeUI() == NORMAL_TREE)
  1571. {
  1572. if (v_oTree.getSelectionMode() == CONTIGUOUS_TREE_SELECTION && this.isSelected() == false && this.getNodeType() == TREE_FOLDER && this.getChildrenLength() == this.getSelectedChildrenCount()) {
  1573. this.m_bSelected = true;
  1574. }
  1575. var labelElem = this.getLabel(this.getTree().getName());
  1576. if (labelElem != null) {
  1577. v_oTree.updateLabelClass(labelElem, getClassName(this, v_oTree), this);
  1578. }
  1579. }
  1580. else
  1581. {
  1582. var checkbox = this.getCheckbox(v_oTree.getName());
  1583. if (checkbox != null) {
  1584. updateCheckboxClass(checkbox, this);
  1585. }
  1586. }
  1587. };
  1588. //open: specifies whether the children of a container node should be displayed
  1589. CInnerTreeNode.prototype.isClosed = function ()
  1590. {
  1591. return !this.m_bOpen;
  1592. };
  1593. //return the child at the appropriate position
  1594. CInnerTreeNode.prototype.getFirstChild = function ()
  1595. {
  1596. var v_oResult = null;
  1597. if ( this.getChildrenLength() > 0 )
  1598. {
  1599. v_oResult = this.m_oChildren[0];
  1600. }
  1601. return v_oResult;
  1602. };
  1603. //return the child at the appropriate position
  1604. CInnerTreeNode.prototype.getLastChild = function ()
  1605. {
  1606. var v_oResult = null;
  1607. if ( this.getChildrenLength() > 0 )
  1608. {
  1609. v_oResult = this.m_oChildren[this.getChildrenLength() - 1];
  1610. }
  1611. return v_oResult;
  1612. };
  1613. var TREE_IMG =
  1614. {
  1615. 'TREE_L':
  1616. {
  1617. 'MINUS': TREE_L_MINUS,
  1618. 'PLUS' : TREE_L_PLUS,
  1619. 'ONLY' : TREE_L_ONLY
  1620. },
  1621. 'TREE_T':
  1622. {
  1623. 'MINUS': TREE_T_MINUS,
  1624. 'PLUS' : TREE_T_PLUS,
  1625. 'ONLY' : TREE_T_ONLY
  1626. }
  1627. };
  1628. // overrides parent method to create a new node of the same class
  1629. CInnerTreeNode.prototype.createNewNode = function(treeNode, tntGeneric,name, value, isSelected)
  1630. {
  1631. // ( oParentTreeNode, oTreeNodeType, bOpenState, sName, value, bSelected )
  1632. new CInnerTreeNode(treeNode, tntGeneric, false, jsDecodeStr(name), jsDecodeStr(value), isSelected);
  1633. };
  1634. function updateCheckboxClass(checkbox, node)
  1635. {
  1636. var checkBoxClass = K_PRMT_sEMPTY;
  1637. var checked = true;
  1638. var ariaChecked = "true";
  1639. //get the current state
  1640. switch (node.getState())
  1641. {
  1642. case NODE_UNSELECTED:
  1643. checkBoxClass = K_PRMT_CSS_CHECKBOX;
  1644. checked = false;
  1645. ariaChecked = "false";
  1646. break;
  1647. case NODE_PARTIAL:
  1648. checkBoxClass = K_PRMT_CSS_CHECKBOX_PARTIAL;
  1649. ariaChecked = "mixed";
  1650. break;
  1651. case NODE_SELECTED:
  1652. checkBoxClass = K_PRMT_CSS_CHECKBOX_CHECKED;
  1653. break;
  1654. }
  1655. checkbox.className = checkBoxClass;
  1656. checkbox.firstChild.checked = checked;
  1657. checkbox.firstChild.setAttribute("checked", checked);
  1658. updateLabelAriaChecked(node.getLabel(node.getTree().getName()), node, ariaChecked);
  1659. }
  1660. /**
  1661. *
  1662. */
  1663. function updateLabelAriaChecked(labelElem, node, ariaChecked)
  1664. {
  1665. if (typeof ariaChecked == K_PRMT_sUNDEFINED) {
  1666. ariaChecked = node2AriaChecked(node);
  1667. }
  1668. if (labelElem) {
  1669. if (labelElem[K_PRMT_ARIA_CHECKED]) {
  1670. labelElem[K_PRMT_ARIA_CHECKED] = ariaChecked;
  1671. }
  1672. else {
  1673. labelElem.setAttribute(K_PRMT_ARIA_CHECKED, ariaChecked);
  1674. }
  1675. }
  1676. }
  1677. /**
  1678. * Maps the aria-checked to the node state : NODE_UNSELECTED => "false", NODE_PARTIAL => "mixed", NODE_SELECTED => "true"
  1679. */
  1680. function node2AriaChecked(node)
  1681. {
  1682. if (node && node.getState) {
  1683. var nodeState = node.getState();
  1684. return (nodeState == NODE_UNSELECTED? "false" :(nodeState == NODE_PARTIAL? "mixed":"true"));
  1685. }
  1686. }
  1687. function updateToggleIcon(oNode, sTreeName)
  1688. {
  1689. //update the icons
  1690. var icon = document.getElementById(sTreeName + oNode.getTreeRef() + gsCTREE_icon);
  1691. if (icon)
  1692. {
  1693. //icon.src = getIconSrc(oNode);
  1694. var toggleIcon = document.getElementById(sTreeName + oNode.getTreeRef() + gsCTREE_toggle + oNode.getTreeHierarchy());
  1695. //toggleIcon.src = getToggleSrc(oNode);
  1696. toggleIcon.className = getToggleClassName(oNode);
  1697. toggleIcon.title = getToggleTitle(oNode);
  1698. var toggleText = ((toggleIcon.className == K_PRMT_TREE_TOGGLE_OPENED + oNode.m_oRoot.m_oTree.m_sDirection) ? "-" : "+");
  1699. var v_oTextSpanNode = toggleIcon.nextSibling;
  1700. if (v_oTextSpanNode.textContent) {
  1701. v_oTextSpanNode.textContent = toggleText;
  1702. } else { //support IE
  1703. v_oTextSpanNode.firstChild.data = toggleText;
  1704. }
  1705. }
  1706. }
  1707. //return plus or minus icons for the given node
  1708. function getToggleClassName(node)
  1709. {
  1710. if (node.isOpen() == true)
  1711. {
  1712. return ( K_PRMT_TREE_TOGGLE_OPENED + node.m_oRoot.m_oTree.m_sDirection );
  1713. }
  1714. else
  1715. {
  1716. return ( K_PRMT_TREE_TOGGLE_CLOSED + node.m_oRoot.m_oTree.m_sDirection );
  1717. }
  1718. }