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

aui-tree-node-debug.js 34KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694
  1. AUI.add('aui-tree-node', function(A) {
  2. /**
  3. * The TreeNode Utility
  4. *
  5. * @module aui-tree
  6. * @submodule aui-tree-node
  7. */
  8. var Lang = A.Lang,
  9. isString = Lang.isString,
  10. isBoolean = Lang.isBoolean,
  11. ALWAYS_SHOW_HITAREA = 'alwaysShowHitArea',
  12. BLANK = '',
  13. BOUNDING_BOX = 'boundingBox',
  14. CHILDREN = 'children',
  15. CLEARFIX = 'clearfix',
  16. COLLAPSED = 'collapsed',
  17. CONTAINER = 'container',
  18. CONTENT = 'content',
  19. CONTENT_BOX = 'contentBox',
  20. DRAGGABLE = 'draggable',
  21. EXPANDED = 'expanded',
  22. HELPER = 'helper',
  23. HIDDEN = 'hidden',
  24. HIT_AREA_EL = 'hitAreaEl',
  25. HITAREA = 'hitarea',
  26. ICON = 'icon',
  27. ICON_EL = 'iconEl',
  28. INVALID = 'invalid',
  29. ID = 'id',
  30. LABEL = 'label',
  31. LABEL_EL = 'labelEl',
  32. LAST_SELECTED = 'lastSelected',
  33. LEAF = 'leaf',
  34. NODE = 'node',
  35. OVER = 'over',
  36. OWNER_TREE = 'ownerTree',
  37. PARENT_NODE = 'parentNode',
  38. RADIO = 'radio',
  39. RENDERED = 'rendered',
  40. SELECTED = 'selected',
  41. SPACE = ' ',
  42. TREE = 'tree',
  43. TREE_NODE = 'tree-node',
  44. concat = function() {
  45. return Array.prototype.slice.call(arguments).join(SPACE);
  46. },
  47. isTreeNode = function(v) {
  48. return (v instanceof A.TreeNode);
  49. },
  50. isTreeView = function(v) {
  51. return (v instanceof A.TreeView);
  52. },
  53. getCN = A.getClassName,
  54. CSS_HELPER_CLEARFIX = getCN(HELPER, CLEARFIX),
  55. CSS_TREE_COLLAPSED = getCN(TREE, COLLAPSED),
  56. CSS_TREE_CONTAINER = getCN(TREE, CONTAINER),
  57. CSS_TREE_CONTENT_BOX = getCN(TREE, CONTENT_BOX),
  58. CSS_TREE_EXPANDED = getCN(TREE, EXPANDED),
  59. CSS_TREE_HIDDEN = getCN(TREE, HIDDEN),
  60. CSS_TREE_HITAREA = getCN(TREE, HITAREA),
  61. CSS_TREE_ICON = getCN(TREE, ICON),
  62. CSS_TREE_LABEL = getCN(TREE, LABEL),
  63. CSS_TREE_NODE = getCN(TREE, NODE),
  64. CSS_TREE_NODE_CONTENT = getCN(TREE, NODE, CONTENT),
  65. CSS_TREE_NODE_CONTENT_INVALID = getCN(TREE, NODE, CONTENT, INVALID),
  66. CSS_TREE_NODE_HIDDEN_HITAREA = getCN(TREE, NODE, HIDDEN, HITAREA),
  67. CSS_TREE_NODE_LEAF = getCN(TREE, NODE, LEAF),
  68. CSS_TREE_NODE_OVER = getCN(TREE, NODE, OVER),
  69. CSS_TREE_NODE_SELECTED = getCN(TREE, NODE, SELECTED),
  70. HIT_AREA_TPL = '<div class="' + CSS_TREE_HITAREA + '"></div>',
  71. ICON_TPL = '<div class="' + CSS_TREE_ICON + '"></div>',
  72. LABEL_TPL = '<div class="' + CSS_TREE_LABEL + '"></div>',
  73. NODE_CONTAINER_TPL = '<ul></ul>',
  74. NODE_BOUNDING_TEMPLATE = '<li class="' + CSS_TREE_NODE + '"></li>',
  75. NODE_CONTENT_TEMPLATE = '<div class="' + concat(CSS_HELPER_CLEARFIX, CSS_TREE_NODE_CONTENT) + '"></div>';
  76. /**
  77. * A base class for TreeNode, providing:
  78. * <ul>
  79. * <li>Widget Lifecycle (initializer, renderUI, bindUI, syncUI, destructor)</li>
  80. * <li>The node for the TreeView component</li>
  81. * </ul>
  82. *
  83. * Quick Example:<br/>
  84. *
  85. * <pre><code>var instance = new A.TreeNode({
  86. boundingBox: ''
  87. }).render();
  88. * </code></pre>
  89. *
  90. * Check the list of <a href="TreeNode.html#configattributes">Configuration Attributes</a> available for
  91. * TreeNode.
  92. *
  93. * @param config {Object} Object literal specifying widget configuration properties.
  94. *
  95. * @class TreeNode
  96. * @constructor
  97. * @extends TreeData
  98. */
  99. var TreeNode = A.Component.create(
  100. {
  101. /**
  102. * Static property provides a string to identify the class.
  103. *
  104. * @property TreeNode.NAME
  105. * @type String
  106. * @static
  107. */
  108. NAME: TREE_NODE,
  109. /**
  110. * Static property used to define the default attribute
  111. * configuration for the TreeNode.
  112. *
  113. * @property TreeNode.ATTRS
  114. * @type Object
  115. * @static
  116. */
  117. ATTRS: {
  118. /**
  119. * Always show the hitarea icon.
  120. *
  121. * @attribute alwaysShowHitArea
  122. * @default true
  123. * @type boolean
  124. */
  125. alwaysShowHitArea: {
  126. validator: isBoolean,
  127. value: true
  128. },
  129. boundingBox: {
  130. valueFn: function() {
  131. return A.Node.create(NODE_BOUNDING_TEMPLATE);
  132. }
  133. },
  134. contentBox: {
  135. valueFn: function() {
  136. return A.Node.create(NODE_CONTENT_TEMPLATE);
  137. }
  138. },
  139. /**
  140. * If true the TreeNode is draggable.
  141. *
  142. * @attribute draggable
  143. * @default true
  144. * @type boolean
  145. */
  146. draggable: {
  147. validator: isBoolean,
  148. value: true
  149. },
  150. /**
  151. * Whether the TreeNode is expanded by default.
  152. *
  153. * @attribute expanded
  154. * @default false
  155. * @type boolean
  156. */
  157. expanded: {
  158. validator: isBoolean,
  159. value: false
  160. },
  161. /**
  162. * Hitarea element.
  163. *
  164. * @attribute hitAreaEl
  165. * @default Generated DOM element.
  166. * @type Node | String
  167. */
  168. hitAreaEl: {
  169. setter: A.one,
  170. valueFn: function() {
  171. return A.Node.create(HIT_AREA_TPL);
  172. }
  173. },
  174. /**
  175. * Icon element.
  176. *
  177. * @attribute iconEl
  178. * @type Node | String
  179. */
  180. iconEl: {
  181. setter: A.one,
  182. valueFn: function() {
  183. return A.Node.create(ICON_TPL);
  184. }
  185. },
  186. /**
  187. * Id of the TreeNode.
  188. *
  189. * @attribute id
  190. * @default null
  191. * @type String
  192. */
  193. id: {
  194. validator: isString,
  195. valueFn: function() {
  196. return A.guid();
  197. }
  198. },
  199. /**
  200. * Label of the TreeNode.
  201. *
  202. * @attribute label
  203. * @default ''
  204. * @type String
  205. */
  206. label: {
  207. validator: isString,
  208. value: BLANK
  209. },
  210. /**
  211. * Label element to house the <code>label</code> attribute.
  212. *
  213. * @attribute labelEl
  214. * @default Generated DOM element.
  215. * @type Node | String
  216. */
  217. labelEl: {
  218. setter: A.one,
  219. valueFn: function() {
  220. var instance = this;
  221. var label = instance.get(LABEL);
  222. return A.Node.create(LABEL_TPL).html(label).unselectable();
  223. }
  224. },
  225. /**
  226. * Whether the TreeNode could have children or not (i.e. if any
  227. * children is present the TreeNode is a leaf).
  228. *
  229. * @attribute leaf
  230. * @default true
  231. * @type boolean
  232. */
  233. leaf: {
  234. setter: function(v) {
  235. var instance = this;
  236. // if has children it's not a leaf
  237. if (v && instance.get(CHILDREN).length) {
  238. return false;
  239. }
  240. return v;
  241. },
  242. validator: isBoolean,
  243. value: true
  244. },
  245. /**
  246. * Next sibling of the current TreeNode.
  247. *
  248. * @attribute nextSibling
  249. * @default null
  250. * @type TreeNode
  251. */
  252. nextSibling: {
  253. getter: '_getSibling',
  254. validator: isTreeNode,
  255. value: null
  256. },
  257. /**
  258. * TreeView which contains the current TreeNode.
  259. *
  260. * @attribute ownerTree
  261. * @default null
  262. * @type TreeView
  263. */
  264. ownerTree: {
  265. value: null
  266. },
  267. /**
  268. * Parent node of the current TreeNode.
  269. *
  270. * @attribute parentNode
  271. * @default null
  272. * @type TreeNode
  273. */
  274. parentNode: {
  275. validator: function(val) {
  276. return isTreeNode(val) || isTreeView(val);
  277. },
  278. value: null
  279. },
  280. /**
  281. * Previous sibling of the current TreeNode.
  282. *
  283. * @attribute prevSibling
  284. * @default null
  285. * @type TreeNode
  286. */
  287. prevSibling: {
  288. getter: '_getSibling',
  289. validator: isTreeNode,
  290. value: null
  291. },
  292. rendered: {
  293. validator: isBoolean,
  294. value: false
  295. },
  296. tabIndex: {
  297. value: null
  298. }
  299. },
  300. AUGMENTS: [A.TreeData],
  301. EXTENDS: A.Base,
  302. prototype: {
  303. /**
  304. * Replaced BOUNDING_TEMPLATE with NODE_BOUNDING_TEMPLATE.
  305. *
  306. * @property BOUNDING_TEMPLATE
  307. * @type String
  308. * @protected
  309. */
  310. BOUNDING_TEMPLATE: NODE_BOUNDING_TEMPLATE,
  311. /**
  312. * Replaced CONTENT_TEMPLATE with NODE_CONTENT_TEMPLATE.
  313. *
  314. * @property CONTENT_TEMPLATE
  315. * @type String
  316. * @protected
  317. */
  318. CONTENT_TEMPLATE: NODE_CONTENT_TEMPLATE,
  319. /**
  320. * Construction logic executed during TreeNode instantiation. Lifecycle.
  321. *
  322. * @method initializer
  323. * @protected
  324. */
  325. initializer: function() {
  326. var instance = this;
  327. instance.get(BOUNDING_BOX).setData(TREE_NODE, instance);
  328. // Sync the Widget TreeNode id with the BOUNDING_BOX id
  329. instance._syncTreeNodeBBId();
  330. instance._uiSetDraggable(instance.get(DRAGGABLE));
  331. instance._uiSetExpanded(instance.get(EXPANDED));
  332. instance._uiSetLeaf(instance.get(LEAF));
  333. instance.initTreeData();
  334. },
  335. /**
  336. * Bind the events on the TreeNode UI. Lifecycle.
  337. *
  338. * @method bindUI
  339. * @protected
  340. */
  341. bindUI: function() {
  342. var instance = this;
  343. instance.after('childrenChange', A.bind(instance._afterSetChildren, instance));
  344. instance.after('draggableChange', A.bind(instance._afterDraggableChange, instance));
  345. instance.after('expandedChange', A.bind(instance._afterExpandedChange, instance));
  346. instance.after('idChange', instance._afterSetId, instance);
  347. instance.after('leafChange', A.bind(instance._afterLeafChange, instance));
  348. },
  349. render: function(container) {
  350. var instance = this;
  351. if (!instance.get(RENDERED)) {
  352. instance.renderUI();
  353. instance.bindUI();
  354. instance.syncUI();
  355. instance.set(RENDERED, true);
  356. }
  357. if (container) {
  358. var boundingBox = instance.get(BOUNDING_BOX);
  359. var parentNode = instance.get(PARENT_NODE);
  360. boundingBox.appendTo(container);
  361. if (parentNode) {
  362. var paginator = parentNode.get(PAGINATOR);
  363. if (paginator) {
  364. boundingBox.insertBefore(paginator.element, null);
  365. }
  366. }
  367. }
  368. },
  369. /**
  370. * Create the DOM structure for the TreeNode. Lifecycle.
  371. *
  372. * @method renderUI
  373. * @protected
  374. */
  375. renderUI: function() {
  376. var instance = this;
  377. instance._renderBoundingBox();
  378. instance._renderContentBox();
  379. },
  380. /**
  381. * Sync the TreeNode UI. Lifecycle.
  382. *
  383. * @method syncUI
  384. * @protected
  385. */
  386. syncUI: function() {
  387. var instance = this;
  388. instance._syncIconUI();
  389. },
  390. /*
  391. * Methods
  392. */
  393. append: function(node) {
  394. var instance = this;
  395. instance.appendChild(node);
  396. },
  397. /*
  398. * Methods
  399. */
  400. appendChild: function() {
  401. var instance = this;
  402. if (!instance.isLeaf()) {
  403. A.TreeNode.superclass.appendChild.apply(instance, arguments);
  404. }
  405. },
  406. /**
  407. * Collapse the current TreeNode.
  408. *
  409. * @method collapse
  410. */
  411. collapse: function() {
  412. var instance = this;
  413. instance.set(EXPANDED, false);
  414. },
  415. collapseAll: function() {
  416. var instance = this;
  417. A.TreeNode.superclass.collapseAll.apply(instance, arguments);
  418. // instance is also a node, so collapse itself
  419. instance.collapse();
  420. },
  421. /**
  422. * Check if the current TreeNode contains the passed <code>node</code>.
  423. *
  424. * @method contains
  425. * @param {TreeNode} node
  426. * @return {boolean}
  427. */
  428. contains: function(node) {
  429. var instance = this;
  430. return node.isAncestor(instance);
  431. },
  432. /**
  433. * Expand the current TreeNode.
  434. *
  435. * @method expand
  436. */
  437. expand: function() {
  438. var instance = this;
  439. instance.set(EXPANDED, true);
  440. },
  441. expandAll: function() {
  442. var instance = this;
  443. A.TreeNode.superclass.expandAll.apply(instance, arguments);
  444. // instance is also a node, so expand itself
  445. instance.expand();
  446. },
  447. /**
  448. * Get the depth of the current TreeNode.
  449. *
  450. * @method getDepth
  451. * @return {Number}
  452. */
  453. getDepth: function() {
  454. var instance = this;
  455. var depth = 0;
  456. var parentNode = instance.get(PARENT_NODE);
  457. while (parentNode) {
  458. ++depth;
  459. parentNode = parentNode.get(PARENT_NODE);
  460. }
  461. return depth;
  462. },
  463. hasChildNodes: function() {
  464. var instance = this;
  465. return (!instance.isLeaf() && A.TreeNode.superclass.hasChildNodes.apply(instance, arguments));
  466. },
  467. /*
  468. * Hide hitarea icon.
  469. *
  470. * @method hideHitArea
  471. */
  472. hideHitArea: function() {
  473. var instance = this;
  474. instance.get(HIT_AREA_EL).addClass(CSS_TREE_NODE_HIDDEN_HITAREA);
  475. },
  476. /**
  477. * Whether the current TreeNode is ancestor of the passed <code>node</code> or not.
  478. *
  479. * @method isLeaf
  480. * @return {boolean}
  481. */
  482. isAncestor: function(node) {
  483. var instance = this;
  484. var parentNode = instance.get(PARENT_NODE);
  485. while (parentNode) {
  486. if (parentNode === node) {
  487. return true;
  488. }
  489. parentNode = parentNode.get(PARENT_NODE);
  490. }
  491. return false;
  492. },
  493. /**
  494. * Whether the current TreeNode is a leaf or not.
  495. *
  496. * @method isLeaf
  497. * @return {boolean}
  498. */
  499. isLeaf: function() {
  500. var instance = this;
  501. return instance.get(LEAF);
  502. },
  503. /**
  504. * Whether the current TreeNode is selected or not.
  505. *
  506. * @method isSelected
  507. * @return {boolean}
  508. */
  509. isSelected: function() {
  510. var instance = this;
  511. return instance.get(CONTENT_BOX).hasClass(CSS_TREE_NODE_SELECTED);
  512. },
  513. /*
  514. * Fires when <code>mouseout</code> the current TreeNode.
  515. *
  516. * @method over
  517. */
  518. out: function() {
  519. var instance = this;
  520. instance.get(CONTENT_BOX).removeClass(CSS_TREE_NODE_OVER);
  521. },
  522. /*
  523. * Fires when <code>mouseover</code> the current TreeNode.
  524. *
  525. * @method over
  526. */
  527. over: function() {
  528. var instance = this;
  529. instance.get(CONTENT_BOX).addClass(CSS_TREE_NODE_OVER);
  530. },
  531. /*
  532. * Select the current TreeNode.
  533. *
  534. * @method select
  535. */
  536. select: function() {
  537. var instance = this;
  538. var ownerTree = instance.get(OWNER_TREE);
  539. if (ownerTree) {
  540. ownerTree.set(LAST_SELECTED, instance);
  541. }
  542. instance.get(CONTENT_BOX).addClass(CSS_TREE_NODE_SELECTED);
  543. instance.fire('select');
  544. },
  545. /*
  546. * Show hitarea icon.
  547. *
  548. * @method showHitArea
  549. */
  550. showHitArea: function() {
  551. var instance = this;
  552. instance.get(HIT_AREA_EL).removeClass(CSS_TREE_NODE_HIDDEN_HITAREA);
  553. },
  554. /**
  555. * Toggle the current TreeNode, <code>collapsed</code> or <code>expanded</code>.
  556. *
  557. * @method toggle
  558. */
  559. toggle: function() {
  560. var instance = this;
  561. if (instance.get(EXPANDED)) {
  562. instance.collapse();
  563. }
  564. else {
  565. instance.expand();
  566. }
  567. },
  568. /*
  569. * Unselect the current TreeNode.
  570. *
  571. * @method unselect
  572. */
  573. unselect: function() {
  574. var instance = this;
  575. instance.get(CONTENT_BOX).removeClass(CSS_TREE_NODE_SELECTED);
  576. instance.fire('unselect');
  577. },
  578. /**
  579. * Fire after draggable change.
  580. *
  581. * @method _afterDraggableChange
  582. * @param {EventFacade} event
  583. * @protected
  584. */
  585. _afterDraggableChange: function(event) {
  586. var instance = this;
  587. instance._uiSetDraggable(event.newVal);
  588. instance._syncIconUI();
  589. },
  590. /**
  591. * Fire after expanded change.
  592. *
  593. * @method _afterExpandedChange
  594. * @param {EventFacade} event
  595. * @protected
  596. */
  597. _afterExpandedChange: function(event) {
  598. var instance = this;
  599. instance._uiSetExpanded(event.newVal);
  600. instance._syncIconUI();
  601. },
  602. /**
  603. * Fire after leaf change.
  604. *
  605. * @method _afterLeafChange
  606. * @param {EventFacade} event
  607. * @protected
  608. */
  609. _afterLeafChange: function(event) {
  610. var instance = this;
  611. instance._uiSetLeaf(event.newVal);
  612. instance._syncIconUI();
  613. },
  614. /**
  615. * Fire after loading change.
  616. *
  617. * @method _afterLoadingChange
  618. * @param {EventFacade} event
  619. * @protected
  620. */
  621. _afterLoadingChange: function(event) {
  622. var instance = this;
  623. instance._syncIconUI();
  624. },
  625. /**
  626. * Fire after set children.
  627. *
  628. * @method _afterSetChildren
  629. * @param {EventFacade} event
  630. * @protected
  631. */
  632. _afterSetChildren: function(event) {
  633. var instance = this;
  634. instance._syncIconUI();
  635. },
  636. /**
  637. * Render the node container.
  638. *
  639. * @method _createNodeContainer
  640. * @protected
  641. * @return {Node}
  642. */
  643. _createNodeContainer: function() {
  644. var instance = this;
  645. // creating <ul class="aui-tree-container">
  646. var nodeContainer = instance.get(CONTAINER) || A.Node.create(NODE_CONTAINER_TPL);
  647. nodeContainer.addClass(CSS_TREE_CONTAINER);
  648. // when it's not a leaf it has a <ul> container
  649. instance.set(CONTAINER, nodeContainer);
  650. return nodeContainer;
  651. },
  652. _getSibling: function(value, attrName) {
  653. var instance = this;
  654. var propName = '_' + attrName;
  655. var sibling = instance[propName];
  656. if (sibling !== null && !isTreeNode(sibling)) {
  657. sibling = null;
  658. instance[propName] = sibling;
  659. }
  660. return sibling;
  661. },
  662. /**
  663. * Render the <code>boundingBox</code> node.
  664. *
  665. * @method _renderBoundingBox
  666. * @protected
  667. * @return {Node}
  668. */
  669. _renderBoundingBox: function() {
  670. var instance = this;
  671. var boundingBox = instance.get(BOUNDING_BOX);
  672. var contentBox = instance.get(CONTENT_BOX);
  673. contentBox.append(instance.get(ICON_EL));
  674. contentBox.append(instance.get(LABEL_EL));
  675. boundingBox.append(contentBox);
  676. var nodeContainer = instance.get(CONTAINER);
  677. if (nodeContainer) {
  678. if (!instance.get(EXPANDED)) {
  679. nodeContainer.addClass(CSS_TREE_HIDDEN);
  680. }
  681. boundingBox.append(nodeContainer);
  682. }
  683. return boundingBox;
  684. },
  685. /**
  686. * Render the <code>contentBox</code> node.
  687. *
  688. * @method _renderContentBox
  689. * @protected
  690. * @return {Node}
  691. */
  692. _renderContentBox: function(v) {
  693. var instance = this;
  694. var contentBox = instance.get(CONTENT_BOX);
  695. if (!instance.isLeaf()) {
  696. var expanded = instance.get(EXPANDED);
  697. // add folder css classes state
  698. contentBox.addClass(
  699. expanded ? CSS_TREE_EXPANDED : CSS_TREE_COLLAPSED
  700. );
  701. if (expanded) {
  702. instance.expand();
  703. }
  704. }
  705. return contentBox;
  706. },
  707. /**
  708. * Sync the hitarea UI.
  709. *
  710. * @method _syncHitArea
  711. * @protected
  712. */
  713. _syncHitArea: function() {
  714. var instance = this;
  715. if (instance.get(ALWAYS_SHOW_HITAREA) || instance.getChildrenLength()) {
  716. instance.showHitArea();
  717. }
  718. else {
  719. instance.hideHitArea();
  720. instance.collapse();
  721. }
  722. },
  723. /**
  724. * Sync the hitarea UI.
  725. *
  726. * @method _syncIconUI
  727. * @param {Array} children
  728. * @protected
  729. */
  730. _syncIconUI: function() {
  731. var instance = this;
  732. instance._syncHitArea();
  733. },
  734. /**
  735. * Set the <code>boundingBox</code> id.
  736. *
  737. * @method _syncTreeNodeBBId
  738. * @param {String} id
  739. * @protected
  740. */
  741. _syncTreeNodeBBId: function(id) {
  742. var instance = this;
  743. instance.get(BOUNDING_BOX).attr(
  744. ID,
  745. instance.get(ID)
  746. );
  747. },
  748. _uiSetDraggable: function(val) {
  749. var instance = this;
  750. var contentBox = instance.get(CONTENT_BOX);
  751. contentBox.toggleClass(CSS_TREE_NODE_CONTENT_INVALID, !val);
  752. },
  753. _uiSetExpanded: function(val) {
  754. var instance = this;
  755. if (!instance.isLeaf()) {
  756. var container = instance.get(CONTAINER);
  757. var contentBox = instance.get(CONTENT_BOX);
  758. if (val) {
  759. contentBox.replaceClass(CSS_TREE_COLLAPSED, CSS_TREE_EXPANDED);
  760. if (container) {
  761. container.removeClass(CSS_TREE_HIDDEN);
  762. }
  763. }
  764. else {
  765. contentBox.replaceClass(CSS_TREE_EXPANDED, CSS_TREE_COLLAPSED);
  766. if (container) {
  767. container.addClass(CSS_TREE_HIDDEN);
  768. }
  769. }
  770. }
  771. },
  772. _uiSetLeaf: function(val) {
  773. var instance = this;
  774. var contentBox = instance.get(CONTENT_BOX);
  775. if (val) {
  776. instance.get(CONTAINER).remove();
  777. instance.get(HIT_AREA_EL).remove();
  778. }
  779. else {
  780. // append hitarea element
  781. contentBox.prepend( instance.get(HIT_AREA_EL) );
  782. // if has children append them to this model
  783. instance._createNodeContainer();
  784. instance._uiSetExpanded(instance.get(EXPANDED));
  785. }
  786. // add leaf css classes
  787. contentBox.toggleClass(CSS_TREE_NODE_LEAF, val);
  788. }
  789. }
  790. }
  791. );
  792. A.TreeNode = TreeNode;
  793. /*
  794. * TreeNodeIO
  795. */
  796. var isFunction = Lang.isFunction,
  797. CACHE = 'cache',
  798. IO = 'io',
  799. LOADED = 'loaded',
  800. LOADING = 'loading',
  801. PAGINATOR = 'paginator',
  802. TREE_NODE_IO = 'tree-node-io',
  803. CSS_TREE_NODE_IO_LOADING = getCN(TREE, NODE, IO, LOADING);
  804. /**
  805. * A base class for TreeNodeIO, providing:
  806. * <ul>
  807. * <li>Widget Lifecycle (initializer, renderUI, bindUI, syncUI, destructor)</li>
  808. * <li>Ajax support to load the children of the current TreeNode</li>
  809. * </ul>
  810. *
  811. * Quick Example:<br/>
  812. *
  813. * <pre><code>var treeNodeIO = new A.TreeNodeIO({
  814. * label: 'TreeNodeIO',
  815. * cache: false,
  816. * io: {
  817. * url: 'assets/content.html'
  818. * }
  819. * });
  820. * </code></pre>
  821. *
  822. * Check the list of <a href="TreeNodeIO.html#configattributes">Configuration Attributes</a> available for
  823. * TreeNodeIO.
  824. *
  825. * @param config {Object} Object literal specifying widget configuration properties.
  826. *
  827. * @class TreeNodeIO
  828. * @constructor
  829. * @extends TreeNode
  830. */
  831. var TreeNodeIO = A.Component.create(
  832. {
  833. /**
  834. * Static property provides a string to identify the class.
  835. *
  836. * @property TreeNode.NAME
  837. * @type String
  838. * @static
  839. */
  840. NAME: TREE_NODE_IO,
  841. /**
  842. * Static property used to define the default attribute
  843. * configuration for the TreeNode.
  844. *
  845. * @property TreeNode.ATTRS
  846. * @type Object
  847. * @static
  848. */
  849. ATTRS: {
  850. /**
  851. * Whether the current TreeNode should cache the loaded content or not.
  852. *
  853. * @attribute cache
  854. * @default true
  855. * @type boolean
  856. */
  857. cache: {
  858. validator: isBoolean,
  859. value: true
  860. },
  861. leaf: {
  862. validator: isBoolean,
  863. value: false
  864. },
  865. /**
  866. * Whether the current TreeNode has loaded the content.
  867. *
  868. * @attribute loaded
  869. * @default false
  870. * @type boolean
  871. */
  872. loaded: {
  873. validator: isBoolean,
  874. value: false
  875. },
  876. /**
  877. * Whether the current TreeNode IO transaction is loading.
  878. *
  879. * @attribute loading
  880. * @default false
  881. * @type boolean
  882. */
  883. loading: {
  884. validator: isBoolean,
  885. value: false
  886. }
  887. },
  888. AUGMENTS: [A.TreeViewPaginator, A.TreeViewIO],
  889. EXTENDS: A.TreeNode,
  890. prototype: {
  891. /**
  892. * Bind the events on the TreeNodeIO UI. Lifecycle.
  893. *
  894. * @method bindUI
  895. * @protected
  896. */
  897. bindUI: function() {
  898. var instance = this;
  899. A.TreeNodeIO.superclass.bindUI.apply(instance, arguments);
  900. instance.on('ioRequestSuccess', instance._onIOSuccess, instance);
  901. },
  902. syncUI: function() {
  903. var instance = this;
  904. A.TreeNodeIO.superclass.syncUI.apply(instance, arguments);
  905. },
  906. /*
  907. * Methods
  908. */
  909. expand: function() {
  910. var instance = this;
  911. var cache = instance.get(CACHE);
  912. var io = instance.get(IO);
  913. var loaded = instance.get(LOADED);
  914. var loading = instance.get(LOADING);
  915. if (!cache) {
  916. // if cache is false on expand, always set LOADED to false
  917. instance.set(LOADED, false);
  918. }
  919. if (io && !loaded && !loading && !instance.hasChildNodes()) {
  920. if (!cache) {
  921. // remove all children to reload
  922. instance.empty();
  923. }
  924. instance.initIO();
  925. }
  926. else {
  927. A.TreeNodeIO.superclass.expand.apply(instance, arguments);
  928. }
  929. },
  930. /**
  931. * If not specified on the TreeNode some attributes are inherited from the
  932. * ownerTree by this method.
  933. *
  934. * @method _inheritOwnerTreeAttrs
  935. * @protected
  936. */
  937. _inheritOwnerTreeAttrs: function() {
  938. var instance = this;
  939. var ownerTree = instance.get(OWNER_TREE);
  940. if (ownerTree) {
  941. if (!instance.get(IO)) {
  942. var io = A.clone(
  943. ownerTree.get(IO),
  944. true,
  945. function(value, key) {
  946. if (isFunction(value) && (value.defaultFn || value.wrappedFn)) {
  947. return false;
  948. }
  949. return true;
  950. }
  951. );
  952. instance.set(IO, io);
  953. }
  954. if (!instance.get(PAGINATOR)) {
  955. var ownerTreePaginator = ownerTree.get(PAGINATOR);
  956. var paginator = A.clone(ownerTreePaginator);
  957. // make sure we are not using the same element passed to the ownerTree on the TreeNode
  958. if (paginator && paginator.element) {
  959. paginator.element = ownerTreePaginator.element.clone();
  960. }
  961. instance.set(PAGINATOR, paginator);
  962. }
  963. }
  964. },
  965. _onIOSuccess: function(event) {
  966. var instance = this;
  967. instance.expand();
  968. }
  969. }
  970. }
  971. );
  972. A.TreeNodeIO = TreeNodeIO;
  973. /*
  974. * TreeNodeCheck
  975. */
  976. var CHECKBOX = 'checkbox',
  977. CHECKED = 'checked',
  978. CHECK_CONTAINER_EL = 'checkContainerEl',
  979. CHECK_EL = 'checkEl',
  980. CHECK_NAME = 'checkName',
  981. DOT = '.',
  982. NAME = 'name',
  983. TREE_NODE_CHECK = 'tree-node-check',
  984. CSS_TREE_NODE_CHECKBOX = getCN(TREE, NODE, CHECKBOX),
  985. CSS_TREE_NODE_CHECKBOX_CONTAINER = getCN(TREE, NODE, CHECKBOX, CONTAINER),
  986. CSS_TREE_NODE_CHECKED = getCN(TREE, NODE, CHECKED),
  987. CHECKBOX_CONTAINER_TPL = '<div class="' + CSS_TREE_NODE_CHECKBOX_CONTAINER + '"></div>',
  988. CHECKBOX_TPL = '<input class="' + CSS_TREE_NODE_CHECKBOX + '" type="checkbox" />';
  989. /**
  990. * <p><img src="assets/images/aui-tree-nod-check/main.png"/></p>
  991. *
  992. * A base class for TreeNodeCheck, providing:
  993. * <ul>
  994. * <li>Widget Lifecycle (initializer, renderUI, bindUI, syncUI, destructor)</li>
  995. * <li>Checkbox support for the TreeNode</li>
  996. * </ul>
  997. *
  998. * Check the list of <a href="TreeNodeCheck.html#configattributes">Configuration Attributes</a> available for
  999. * TreeNodeCheck.
  1000. *
  1001. * @param config {Object} Object literal specifying widget configuration properties.
  1002. *
  1003. * @class TreeNodeCheck
  1004. * @constructor
  1005. * @extends TreeNodeIO
  1006. */
  1007. var TreeNodeCheck = A.Component.create(
  1008. {
  1009. /**
  1010. * Static property provides a string to identify the class.
  1011. *
  1012. * @property TreeNode.NAME
  1013. * @type String
  1014. * @static
  1015. */
  1016. NAME: TREE_NODE_CHECK,
  1017. /**
  1018. * Static property used to define the default attribute
  1019. * configuration for the TreeNode.
  1020. *
  1021. * @property TreeNode.ATTRS
  1022. * @type Object
  1023. * @static
  1024. */
  1025. ATTRS: {
  1026. /**
  1027. * Whether the TreeNode is checked or not.
  1028. *
  1029. * @attribute checked
  1030. * @default false
  1031. * @type boolean
  1032. */
  1033. checked: {
  1034. validator: isBoolean,
  1035. value: false
  1036. },
  1037. /**
  1038. * Container element for the checkbox.
  1039. *
  1040. * @attribute checkContainerEl
  1041. * @default Generated DOM element.
  1042. * @type Node | String
  1043. */
  1044. checkContainerEl: {
  1045. setter: A.one,
  1046. valueFn: function() {
  1047. return A.Node.create(CHECKBOX_CONTAINER_TPL);
  1048. }
  1049. },
  1050. /**
  1051. * Checkbox element.
  1052. *
  1053. * @attribute checkEl
  1054. * @default Generated DOM element.
  1055. * @type Node | String
  1056. */
  1057. checkEl: {
  1058. setter: A.one,
  1059. valueFn: function() {
  1060. var instance = this;
  1061. var checkBoxId = instance.get(ID) + 'Checkbox';
  1062. var attributes = {
  1063. ID: checkBoxId,
  1064. NAME: instance.get(CHECK_NAME)
  1065. };
  1066. return A.Node.create(CHECKBOX_TPL).attr(attributes);
  1067. }
  1068. },
  1069. /**
  1070. * Name of the checkbox element used on the current TreeNode.
  1071. *
  1072. * @attribute checkName
  1073. * @default 'tree-node-check'
  1074. * @type String
  1075. */
  1076. checkName: {
  1077. value: TREE_NODE_CHECK,
  1078. validator: isString
  1079. }
  1080. },
  1081. EXTENDS: A.TreeNodeIO,
  1082. prototype: {
  1083. initializer: function() {
  1084. var instance = this;
  1085. instance._uiSetChecked(instance.get(CHECKED));
  1086. },
  1087. /*
  1088. * Lifecycle
  1089. */
  1090. renderUI: function() {
  1091. var instance = this;
  1092. A.TreeNodeCheck.superclass.renderUI.apply(instance, arguments);
  1093. var checkEl = instance.get(CHECK_EL);
  1094. var checkContainerEl = instance.get(CHECK_CONTAINER_EL);
  1095. checkEl.hide();
  1096. checkContainerEl.append(checkEl);
  1097. instance.get(LABEL_EL).placeBefore(checkContainerEl);
  1098. if (instance.isChecked()) {
  1099. instance.check();
  1100. }
  1101. },
  1102. bindUI: function() {
  1103. var instance = this;
  1104. var contentBox = instance.get(CONTENT_BOX);
  1105. A.TreeNodeCheck.superclass.bindUI.apply(instance, arguments);
  1106. instance.after('checkedChange', A.bind(instance._afterCheckedChange, instance));
  1107. contentBox.delegate('click', A.bind(instance.toggleCheck, instance), DOT + CSS_TREE_NODE_CHECKBOX_CONTAINER);
  1108. contentBox.delegate('click', A.bind(instance.toggleCheck, instance), DOT + CSS_TREE_LABEL);
  1109. // cancel dblclick because of the check
  1110. instance.get(LABEL_EL).swallowEvent('dblclick');
  1111. },
  1112. /**
  1113. * Check the current TreeNode.
  1114. *
  1115. * @method check
  1116. */
  1117. check: function(originalTarget) {
  1118. var instance = this;
  1119. instance.set(
  1120. CHECKED,
  1121. true,
  1122. {
  1123. originalTarget: originalTarget
  1124. }
  1125. );
  1126. },
  1127. /*
  1128. * Whether the current TreeNodeCheck is checked.
  1129. *
  1130. * @method isChecked
  1131. * @return boolean
  1132. */
  1133. isChecked: function() {
  1134. var instance = this;
  1135. return instance.get(CHECKED);
  1136. },
  1137. /**
  1138. * Toggle the check status of the current TreeNode.
  1139. *
  1140. * @method toggleCheck
  1141. */
  1142. toggleCheck: function() {
  1143. var instance = this;
  1144. var checkEl = instance.get(CHECK_EL);
  1145. var checked = checkEl.attr(CHECKED);
  1146. if (!checked) {
  1147. instance.check();
  1148. }
  1149. else {
  1150. instance.uncheck();
  1151. }
  1152. },
  1153. /**
  1154. * Uncheck the current TreeNode.
  1155. *
  1156. * @method uncheck
  1157. */
  1158. uncheck: function(originalTarget) {
  1159. var instance = this;
  1160. instance.set(
  1161. CHECKED,
  1162. false,
  1163. {
  1164. originalTarget: originalTarget
  1165. }
  1166. );
  1167. },
  1168. _afterCheckedChange: function(event) {
  1169. var instance = this;
  1170. instance._uiSetChecked(event.newVal);
  1171. },
  1172. _uiSetChecked: function(val) {
  1173. var instance = this;
  1174. var checkEl = instance.get(CHECK_EL);
  1175. var contentBox = instance.get(CONTENT_BOX);
  1176. if (val) {
  1177. contentBox.addClass(CSS_TREE_NODE_CHECKED);
  1178. checkEl.attr(CHECKED, CHECKED);
  1179. }
  1180. else {
  1181. contentBox.removeClass(CSS_TREE_NODE_CHECKED);
  1182. checkEl.attr(CHECKED, BLANK);
  1183. }
  1184. }
  1185. }
  1186. }
  1187. );
  1188. A.TreeNodeCheck = TreeNodeCheck;
  1189. /*
  1190. * TreeNodeTask
  1191. */
  1192. var CHILD = 'child',
  1193. TREE_NODE_TASK = 'tree-node-task',
  1194. UNCHECKED = 'unchecked',
  1195. isTreeNodeTask = function(node) {
  1196. return node instanceof A.TreeNodeCheck;
  1197. },
  1198. CSS_TREE_NODE_CHILD_UNCHECKED = getCN(TREE, NODE, CHILD, UNCHECKED);
  1199. /**
  1200. * <p><img src="assets/images/aui-treeNodeTask/main.png"/></p>
  1201. *
  1202. * A base class for TreeNodeTask, providing:
  1203. * <ul>
  1204. * <li>Widget Lifecycle (initializer, renderUI, bindUI, syncUI, destructor)</li>
  1205. * <li>3 states checkbox support</li>
  1206. * <li>Automatic check/uncheck the parent status based on the children checked status</li>
  1207. * </ul>
  1208. *
  1209. * Check the list of <a href="TreeNodeTask.html#configattributes">Configuration Attributes</a> available for
  1210. * TreeNodeTask.
  1211. *
  1212. * @param config {Object} Object literal specifying widget configuration properties.
  1213. *
  1214. * @class TreeNodeTask
  1215. * @constructor
  1216. * @extends TreeNodeCheck
  1217. */
  1218. var TreeNodeTask = A.Component.create(
  1219. {
  1220. /**
  1221. * Static property provides a string to identify the class.
  1222. *
  1223. * @property TreeNode.NAME
  1224. * @type String
  1225. * @static
  1226. */
  1227. NAME: TREE_NODE_TASK,
  1228. EXTENDS: A.TreeNodeCheck,
  1229. prototype: {
  1230. /*
  1231. * Methods
  1232. */
  1233. check: function(originalTarget) {
  1234. var instance = this;
  1235. originalTarget = originalTarget || instance;
  1236. if (!instance.isLeaf()) {
  1237. instance.eachChildren(
  1238. function(child) {
  1239. if (isTreeNodeTask(child)) {
  1240. child.check(originalTarget);
  1241. }
  1242. }
  1243. );
  1244. }
  1245. instance.eachParent(
  1246. function(parentNode) {
  1247. if (isTreeNodeTask(parentNode)) {
  1248. var parentHasUncheckedDescendants = false;
  1249. parentNode.eachChildren(function(child) {
  1250. if ((child !== instance) && !child.isChecked()) {
  1251. parentHasUncheckedDescendants = true;
  1252. }
  1253. else {
  1254. var childHasUncheckedChild = child.get(CONTENT_BOX).hasClass(CSS_TREE_NODE_CHILD_UNCHECKED);
  1255. if (childHasUncheckedChild) {
  1256. parentHasUncheckedDescendants = true;
  1257. }
  1258. }
  1259. });
  1260. if (!parentHasUncheckedDescendants) {
  1261. parentNode.get(CONTENT_BOX).removeClass(CSS_TREE_NODE_CHILD_UNCHECKED);
  1262. }
  1263. }
  1264. }
  1265. );
  1266. instance.get(CONTENT_BOX).removeClass(CSS_TREE_NODE_CHILD_UNCHECKED);
  1267. // invoke default check logic
  1268. A.TreeNodeTask.superclass.check.call(instance, originalTarget);
  1269. },
  1270. uncheck: function(originalTarget) {
  1271. var instance = this;
  1272. originalTarget = originalTarget || instance;
  1273. if (!instance.isLeaf()) {
  1274. instance.eachChildren(
  1275. function(child) {
  1276. if (child instanceof A.TreeNodeCheck) {
  1277. child.uncheck(originalTarget);
  1278. }
  1279. }
  1280. );
  1281. }
  1282. instance.eachParent(
  1283. function(parentNode) {
  1284. if (isTreeNodeTask(parentNode) && parentNode.isChecked()) {
  1285. parentNode.get(CONTENT_BOX).addClass(CSS_TREE_NODE_CHILD_UNCHECKED);
  1286. }
  1287. }
  1288. );
  1289. instance.get(CONTENT_BOX).removeClass(CSS_TREE_NODE_CHILD_UNCHECKED);
  1290. // invoke default uncheck logic
  1291. A.TreeNodeTask.superclass.uncheck.call(instance, originalTarget);
  1292. }
  1293. }
  1294. }
  1295. );
  1296. A.TreeNodeTask = TreeNodeTask;
  1297. /*
  1298. * TreeNodeRadio
  1299. */
  1300. var TREE_NODE_RADIO = 'tree-node-radio',
  1301. isTreeNodeRadio = function(node) {
  1302. return node instanceof A.TreeNodeRadio;
  1303. },
  1304. CSS_NODE_RADIO = getCN(TREE, NODE, RADIO),
  1305. CSS_NODE_RADIO_CHECKED = getCN(TREE, NODE, RADIO, CHECKED);
  1306. /**
  1307. * <p><img src="assets/images/aui-treeNodeRadio/main.png"/></p>
  1308. *
  1309. * A base class for TreeNodeRadio, providing:
  1310. * <ul>
  1311. * <li>Widget Lifecycle (initializer, renderUI, bindUI, syncUI, destructor)</li>
  1312. * <li>3 states checkbox support</li>
  1313. * <li>Automatic check/uncheck the parent status based on the children checked status</li>
  1314. * </ul>
  1315. *
  1316. * Check the list of <a href="TreeNodeRadio.html#configattributes">Configuration Attributes</a> available for
  1317. * TreeNodeRadio.
  1318. *
  1319. * @param config {Object} Object literal specifying widget configuration properties.
  1320. *
  1321. * @class TreeNodeRadio
  1322. * @constructor
  1323. * @extends TreeNodeTask
  1324. */
  1325. var TreeNodeRadio = A.Component.create(
  1326. {
  1327. /**
  1328. * Static property provides a string to identify the class.
  1329. *
  1330. * @property TreeNode.NAME
  1331. * @type String
  1332. * @static
  1333. */
  1334. NAME: TREE_NODE_RADIO,
  1335. EXTENDS: A.TreeNodeCheck,
  1336. prototype: {
  1337. /*
  1338. * Methods
  1339. */
  1340. renderUI: function() {
  1341. var instance = this;
  1342. A.TreeNodeRadio.superclass.renderUI.apply(instance, arguments);
  1343. instance.get(CONTENT_BOX).addClass(CSS_NODE_RADIO);
  1344. },
  1345. _uncheckNodesRadio: function(node) {
  1346. var instance = this;
  1347. var children;
  1348. if (node) {
  1349. children = node.get(CHILDREN);
  1350. }
  1351. else {
  1352. var ownerTree = instance.get(OWNER_TREE);
  1353. if (ownerTree) {
  1354. children = ownerTree.get(CHILDREN);
  1355. }
  1356. else {
  1357. return;
  1358. }
  1359. }
  1360. A.Array.each(
  1361. children,
  1362. function(value, index, collection) {
  1363. if (!value.isLeaf()) {
  1364. instance._uncheckNodesRadio(value);
  1365. }
  1366. if (isTreeNodeRadio(value)) {
  1367. value.uncheck();
  1368. }
  1369. }
  1370. );
  1371. },
  1372. _uiSetChecked: function(val) {
  1373. var instance = this;
  1374. if (val) {
  1375. instance.get(CONTENT_BOX).addClass(CSS_NODE_RADIO_CHECKED);
  1376. instance.get(CHECK_EL).attr(CHECKED, CHECKED);
  1377. }
  1378. else {
  1379. instance.get(CONTENT_BOX).removeClass(CSS_NODE_RADIO_CHECKED);
  1380. instance.get(CHECK_EL).attr(CHECKED, BLANK);
  1381. }
  1382. },
  1383. check: function() {
  1384. var instance = this;
  1385. instance._uncheckNodesRadio();
  1386. A.TreeNodeRadio.superclass.check.apply(instance, arguments);
  1387. }
  1388. }
  1389. }
  1390. );
  1391. A.TreeNodeRadio = TreeNodeRadio;
  1392. /**
  1393. * TreeNode types hash map.
  1394. *
  1395. * <pre><code>A.TreeNode.nodeTypes = {
  1396. * check: A.TreeNodeCheck,
  1397. * io: A.TreeNodeIO,
  1398. * node: A.TreeNode,
  1399. * radio: A.TreeNodeRadio,
  1400. * task: A.TreeNodeTask
  1401. *};</code></pre>
  1402. *
  1403. * @for TreeNode
  1404. * @property A.TreeNode.nodeTypes
  1405. * @type Object
  1406. */
  1407. A.TreeNode.nodeTypes = {
  1408. check: A.TreeNodeCheck,
  1409. io: A.TreeNodeIO,
  1410. node: A.TreeNode,
  1411. radio: A.TreeNodeRadio,
  1412. task: A.TreeNodeTask
  1413. };
  1414. }, '@VERSION@' ,{requires:['aui-tree-data','aui-tree-io','aui-tree-paginator','json','querystring-stringify'], skinnable:false});