RadMenu.js 25 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219
  1. if (typeof window.RadMenuNamespace == "undefined")
  2. {
  3. window.RadMenuNamespace = {};
  4. }
  5. if (typeof window.RadControlsNamespace == "undefined")
  6. {
  7. window.RadControlsNamespace = {};
  8. }
  9. RadControlsNamespace.AppendStyleSheet = function(callback, clientID, pathToCssFile)
  10. {
  11. if (!pathToCssFile)
  12. {
  13. return;
  14. }
  15. var isGecko = window.netscape && !window.opera;
  16. if (!callback && isGecko)
  17. {
  18. //immediate css loading for Gecko
  19. document.write("<" + "link" + " rel='stylesheet' type='text/css' href='" + pathToCssFile + "' />");
  20. }
  21. else
  22. {
  23. var linkObject = document.createElement("link");
  24. linkObject.rel = "stylesheet";
  25. linkObject.type = "text/css";
  26. linkObject.href = pathToCssFile;
  27. document.getElementsByTagName("head")[0].appendChild(linkObject);
  28. }
  29. };
  30. RadMenuNamespace.ItemFlow = {Vertical : 0, Horizontal : 1};
  31. RadMenuNamespace.ExpandDirection = {Auto : 0, Up : 1, Down : 2, Left : 3, Right : 4};
  32. RadMenuNamespace.ExpandDirectionPropertyName = {"1" : 'bottom', "2" : 'top', "3" : 'right', "4" : 'left'};
  33. function RadMenu (element)
  34. {
  35. this.DomElement = element;
  36. this.ChildItemList = this.DomElement.getElementsByTagName("ul")[0];
  37. this.StateField = document.getElementById(element.id + "_Hidden");
  38. this.Items = [];
  39. this.AllItems = [];
  40. this.OpenedItem = null;
  41. this.LastExpandedItem = null;
  42. this.ExpandAnimation = {};
  43. this.CollapseAnimation = {};
  44. this.CollapseDelay = 500;
  45. this.ExpandDelay = 100;
  46. this.ID = element.id;
  47. this.Skin = "Default";
  48. this.RightToLeft = false;
  49. this.EnableScreenBoundaryDetection = true;
  50. this.InUpdate = false;
  51. this.Initialized = false;
  52. this.State = {};
  53. this.ItemState = {};
  54. this.CausesValidation = true;
  55. this.Flow = RadMenuNamespace.ItemFlow.Horizontal;
  56. this.ClickToOpen = false;
  57. this.Enabled = true;
  58. this.EnableAutoScroll = false;
  59. this.Clicked = false; // click to open flag
  60. this.OriginalZIndex = this.DomElement.style.zIndex;
  61. this.StateFieldDetached = false;
  62. this.Attributes = {};
  63. RadControlsNamespace.EventMixin.Initialize(this);
  64. RadControlsNamespace.DomEventMixin.Initialize(this);
  65. /* if (typeof(RadMenu.initializeBase) == "function")
  66. {
  67. RadMenu.initializeBase(this, [element]);
  68. }*/
  69. }
  70. /*RadControlsNamespace.MsAjaxMixin.Initialize(RadMenu, 'RadMenu');*/
  71. RadMenu.Create = function ()
  72. {
  73. var clientID = arguments[0];
  74. /*
  75. if (typeof ($create) == "function")
  76. {
  77. //the global RadMenu function object
  78. var type = this;
  79. //{name : 'value'} will trigger a menuInstance.set_name('value');
  80. var properties = {};
  81. //{itemClick : OnItemClick} will trigger a menuInstance.add_itemClick(OnItemClick);
  82. var events = {};
  83. //{"Treeview" : "RadTreeView1} will trigger a menuInstance.set_Treeview($find('RadTreeView1'));
  84. var references = {};
  85. //the DOM element that this component will attach to. crucial for partial updates and disposes
  86. var domElement = $get(clientID);
  87. return $create(type, properties, events, references, domElement);
  88. }
  89. else
  90. {*/
  91. var oldMenu = window[clientID];
  92. if (oldMenu != null && oldMenu.Dispose)
  93. {
  94. oldMenu.Dispose();
  95. }
  96. var element = document.getElementById(clientID);
  97. return new this(element);
  98. /*}*/
  99. }
  100. RadMenu.JSONIncludeDeep = { "Attributes" : true };
  101. RadMenu.CreateState = function (instance)
  102. {
  103. instance.InitialState = {};
  104. for (var i in instance)
  105. {
  106. var type = typeof instance[i];
  107. if (type == "number" || type == "string" || type == "boolean")
  108. instance.InitialState[i] = instance[i];
  109. }
  110. }
  111. RadMenu.GetFirstChildByTagName = function(parentNode, tagName)
  112. {
  113. var child = parentNode.getElementsByTagName(tagName)[0];
  114. if (child && child.parentNode == parentNode)
  115. {
  116. return child;
  117. }
  118. return null;
  119. }
  120. RadMenu.prototype.RenderInProgress = function()
  121. {
  122. return this.DomElement.offsetWidth == 0 && RadControlsNamespace.Browser.IsIE;
  123. }
  124. RadMenu.prototype.Detach = function(e)
  125. {
  126. if (!(RadControlsNamespace.Browser.IsIE) || document.readyState == "complete")
  127. {
  128. if (!this.StateFieldDetached)
  129. {
  130. var parentNode = this.DomElement.parentNode;
  131. this.StateField.parentNode.removeChild(this.StateField);
  132. parentNode.insertBefore(this.StateField, this.DomElement);
  133. this.StateFieldDetached = true;
  134. }
  135. //To solve the IE7 issue (disappearing html elements)
  136. this.DomElement.parentNode.removeChild(this.DomElement);
  137. document.forms[0].insertBefore(this.DomElement, document.forms[0].firstChild);
  138. this.DomElement.style.position = "absolute";
  139. this.Detached = true;
  140. }
  141. }
  142. RadMenu.prototype.ReAttach = function(e)
  143. {
  144. if (!(RadControlsNamespace.Browser.IsIE) || document.readyState == "complete")
  145. {
  146. this.DomElement.parentNode.removeChild(this.DomElement);
  147. this.StateField.parentNode.insertBefore(this.DomElement, this.StateField);
  148. this.Detached = false;
  149. }
  150. }
  151. RadMenu.prototype.Show = function(e)
  152. {
  153. if (!this.IsContext)
  154. {
  155. return;
  156. }
  157. if (!this.RaiseEvent("OnClientContextShowing"))
  158. {
  159. return RadControlsNamespace.DomEvent.PreventDefault(e);
  160. }
  161. for (var i in RadMenuNamespace.ContextMenus)
  162. {
  163. RadMenuNamespace.ContextMenus[i].Hide();
  164. }
  165. var x = this.MouseEventX(e);
  166. var y = this.MouseEventY(e);
  167. if (this.RightToLeft)
  168. {
  169. this.ShowAt(x, y);
  170. return this.ShowAt(x - this.ChildItemList.offsetWidth, y);
  171. }
  172. return this.ShowAt(x, y);
  173. }
  174. RadMenu.prototype.CreateRuntimeScroll = function (height)
  175. {
  176. if (this.Scroll)
  177. {
  178. this.Scroll.SetHeight(height);
  179. return;
  180. }
  181. this.BuildScrollObject(true);
  182. this.Scroll.Initialize()
  183. this.ScrollWrap = this.ChildItemList.parentNode;
  184. this.Ease.Element = this.ScrollWrap;
  185. this.Ease.Overlay.Element = this.ScrollWrap;
  186. this.ScrollWrap.className = "scrollWrap " + this.ChildItemList.className;
  187. this.ChildItemList.className = "active vertical";
  188. this.Scroll.SetHeight(height);
  189. }
  190. RadMenu.prototype.ShowAt = function(x, y)
  191. {
  192. if (!this.IsContext)
  193. {
  194. return;
  195. }
  196. if (!this.Detached)
  197. {
  198. this.Detach();
  199. }
  200. this.ShownAsContext = true;
  201. this.Ease.ShowElements();
  202. var documentSize = RadControlsNamespace.Screen.GetViewPortSize();
  203. if (this.EnableAutoScroll && y + this.ChildItemList.offsetHeight > documentSize.height)
  204. {
  205. this.Ease.ShowElements();
  206. this.Ease.UpdateContainerSize();
  207. this.CreateRuntimeScroll(documentSize.height - y + "px");
  208. }
  209. if (this.ScrollWrap)
  210. {
  211. this.ScrollWrap.style.width = this.ChildItemList.offsetWidth + "px";
  212. this.Scroll.Initialize();
  213. }
  214. this.Ease.UpdateContainerSize();
  215. if (!this.WidthFixed)
  216. {
  217. this.WidthFixed = true;
  218. this.FixItemWidth(this);
  219. }
  220. this.Position(x, y);
  221. this.Ease.In();
  222. this.RaiseEvent('OnClientContextShown', null);
  223. return false;
  224. }
  225. RadMenu.prototype.Position = function (x, y)
  226. {
  227. var portSize = RadControlsNamespace.Screen.GetViewPortSize();
  228. x = Math.min(x, portSize.width - this.DomElement.offsetWidth);
  229. y = Math.min(y, portSize.height - this.DomElement.offsetHeight);
  230. if (isNaN(x)) x = 0;
  231. if (isNaN(y)) y = 0;
  232. this.DomElement.style.left = x + "px";
  233. this.DomElement.style.top = y + "px";
  234. }
  235. RadMenu.prototype.MouseEventX = function(e)
  236. {
  237. if (e.pageX)
  238. {
  239. return e.pageX;
  240. }
  241. else if (e.clientX)
  242. {
  243. if (RadControlsNamespace.Browser.StandardsMode)
  244. {
  245. return (e.clientX + document.documentElement.scrollLeft);
  246. }
  247. return (e.clientX + document.body.scrollLeft);
  248. }
  249. };
  250. RadMenu.prototype.MouseEventY = function(e)
  251. {
  252. if (e.pageY)
  253. {
  254. return e.pageY;
  255. }
  256. else if (e.clientY)
  257. {
  258. if (RadControlsNamespace.Browser.StandardsMode)
  259. {
  260. return (e.clientY + document.documentElement.scrollTop);
  261. }
  262. return (e.clientY + document.body.scrollTop);
  263. }
  264. };
  265. RadMenu.prototype.EventSource = function(e)
  266. {
  267. return RadControlsNamespace.DomEvent.GetTarget(e);
  268. }
  269. RadMenu.prototype.Hide = function()
  270. {
  271. if (this.ShownAsContext)
  272. {
  273. if (this.Detached)
  274. {
  275. this.ReAttach();
  276. }
  277. this.Ease.Out();
  278. this.ShownAsContext = false;
  279. this.RaiseEvent('OnClientContextHidden', null);
  280. }
  281. }
  282. RadMenu.prototype.Initialize = function (configObject, itemData)
  283. {
  284. this.LoadConfiguration(configObject);
  285. this.ItemData = itemData;
  286. this.DetermineDirection();
  287. this.ApplyRTL();
  288. if (this.IsContext)
  289. {
  290. this.InitContextMenu();
  291. }
  292. this.CreateControlHierarchy(this, 0);
  293. if (!this.Enabled)
  294. {
  295. this.Disable();
  296. }
  297. if (this.Flow == RadMenuNamespace.ItemFlow.Vertical)
  298. {
  299. this.FixRootItemWidth();
  300. }
  301. this.AttachEventHandlers();
  302. this.Initialized = true;
  303. RadMenu.CreateState(this);
  304. this.RaiseEvent('OnClientLoad', null);
  305. };
  306. RadMenu.prototype.AttachEventHandlers = function ()
  307. {
  308. var instance = this;
  309. this.DomElement.RadShow = function ()
  310. {
  311. if (instance.Flow == RadMenuNamespace.ItemFlow.Vertical)
  312. {
  313. instance.FixRootItemWidth();
  314. }
  315. }
  316. this.AttachDomEvent(window, "unload", "Dispose");
  317. if (!this.ClickToOpen && RadControlsNamespace.Browser.IsIE)
  318. {
  319. this.AttachDomEvent(document, "mouseout", "MouseOutHandler");
  320. }
  321. if (this.ClickToOpen)
  322. {
  323. this.AttachDomEvent(document, "click", "CloseOpenedItems");
  324. }
  325. //To refresh the menu position - required for IE because the menu is relatively positioned.
  326. this.AttachDomEvent(window, "resize", "RefreshPosition");
  327. }
  328. RadMenu.prototype.RefreshPosition = function(e)
  329. {
  330. //Causing infinite window resizing when placed in iframe
  331. if (!this.IsContext)
  332. {
  333. this.DomElement.style.cssText = this.DomElement.style.cssText;
  334. }
  335. }
  336. RadMenu.prototype.MouseOutHandler = function(e)
  337. {
  338. var sourceElement = RadControlsNamespace.DomEvent.GetTarget(e);
  339. var destinationElement = RadControlsNamespace.DomEvent.GetRelatedTarget(e);
  340. if (!destinationElement && !this.IsChildOf(this.DomElement, sourceElement))
  341. {
  342. //The mouse is out of the window or the current frame - close the menu
  343. var instance = this;
  344. setTimeout(function(){ instance.Close(); }, this.CollapseDelay);
  345. }
  346. }
  347. RadMenu.prototype.CloseOpenedItems = function(e)
  348. {
  349. var sourceElement = this.EventSource(e);
  350. if (!this.IsChildOf(this.DomElement, sourceElement))
  351. {
  352. this.Close();
  353. this.Clicked = false;
  354. }
  355. }
  356. RadMenu.prototype.DetermineDirection = function ()
  357. {
  358. var el = this.DomElement;
  359. while (el.tagName.toLowerCase() != 'html')
  360. {
  361. if (el.dir)
  362. {
  363. this.RightToLeft = (el.dir.toLowerCase() == "rtl");
  364. return;
  365. }
  366. el = el.parentNode;
  367. }
  368. this.RightToLeft = false;
  369. }
  370. RadMenu.prototype.ApplyRTL = function ()
  371. {
  372. if (!this.RightToLeft) return;
  373. if (this.RenderInProgress())
  374. {
  375. //When the menu is inside a TABLE call it when the window loads
  376. this.AttachDomEvent(window, "load", "ApplyRTL");
  377. return;
  378. }
  379. this.FixItemWidthInRTL();
  380. if (RadControlsNamespace.Browser.IsIE)
  381. {
  382. this.DomElement.dir = "ltr";
  383. }
  384. if (!this.IsContext)
  385. {
  386. this.DomElement.className += " rtl RadMenu_" + this.Skin + "_rtl";
  387. }
  388. else
  389. {
  390. this.DomElement.className += " rtlcontext RadMenu_" + this.Skin + "_rtl";
  391. }
  392. }
  393. RadMenu.prototype.BuildScrollObject = function (wrapNeeded)
  394. {
  395. var isVertical = RadMenuNamespace.ItemFlow.Vertical == this.Flow;
  396. var options = {PerTabScrolling : false, ScrollButtonsPosition : 1, ScrollPosition : 0};
  397. this.Scroll = new RadControlsNamespace.Scroll(this.ChildItemList, isVertical, options);
  398. this.Scroll.ScrollOnHover = true;
  399. this.Scroll.LeaveGapsForArrows = false;
  400. this.Scroll.WrapNeeded = wrapNeeded;
  401. if (isVertical)
  402. {
  403. this.Scroll.LeftArrowClass = "topArrow";
  404. this.Scroll.LeftArrowClassDisabled = "topArrowDisabled";
  405. this.Scroll.RightArrowClass = "bottomArrow";
  406. this.Scroll.RightArrowClassDisabled = "bottomArrowDisabled";
  407. }
  408. }
  409. RadMenu.prototype.InitContextMenu = function ()
  410. {
  411. if (this.ChildItemList.parentNode != this.DomElement)
  412. {
  413. this.ScrollWrap = this.ChildItemList.parentNode;
  414. this.BuildScrollObject(false);
  415. }
  416. this.Ease = new RadControlsNamespace.Ease(
  417. this.ScrollWrap || this.ChildItemList,
  418. this,
  419. 0,
  420. 0,
  421. null,
  422. true
  423. );
  424. if (this.Ease.Overlay.Shim)
  425. {
  426. this.Ease.Overlay.Shim.id = this.DomElement.id + "IframeOverlay";
  427. }
  428. this.Flow = RadMenuNamespace.ItemFlow.Vertical;
  429. this.Ease.SetSide("top");
  430. if (RadControlsNamespace.Browser.IsOpera)
  431. {
  432. this.AttachDomEvent(document, "mousedown", "OnContextMenu");
  433. }
  434. else
  435. {
  436. this.AttachDomEvent(document, "contextmenu", "OnContextMenu");
  437. }
  438. this.AttachDomEvent(document, "click", "OnDocumentClick");
  439. if (!RadMenuNamespace.ContextMenus)
  440. {
  441. RadMenuNamespace.ContextMenus = {};
  442. }
  443. if (!RadMenuNamespace.ContextElements)
  444. {
  445. RadMenuNamespace.ContextElements = {};
  446. }
  447. if (this.ContextMenuElementID)
  448. {
  449. RadMenuNamespace.ContextElements[this.ContextMenuElementID] = true;
  450. }
  451. RadMenuNamespace.ContextMenus[this.ID] = this;
  452. }
  453. RadMenu.prototype.OnContextMenu = function(e)
  454. {
  455. if (RadControlsNamespace.Browser.IsOpera)
  456. {
  457. if (e.button != 2)
  458. {
  459. return;
  460. }
  461. }
  462. this.ContextElement = document.getElementById(this.ContextMenuElementID);
  463. if (this.ContextMenuElementID && !this.ContextElement)
  464. {
  465. return;
  466. }
  467. var sourceElement = this.EventSource(e);
  468. if (this.ContextElement)
  469. {
  470. if (sourceElement == this.ContextElement || this.IsChildOf(this.ContextElement, sourceElement))
  471. {
  472. this.Show(e);
  473. RadControlsNamespace.DomEvent.PreventDefault(e);
  474. RadControlsNamespace.DomEvent.StopPropagation(e);
  475. }
  476. }
  477. else if (!RadMenuNamespace.ContextElements[sourceElement.id])
  478. {
  479. this.Show(e);
  480. RadControlsNamespace.DomEvent.PreventDefault(e);
  481. RadControlsNamespace.DomEvent.StopPropagation(e);
  482. }
  483. }
  484. RadMenu.prototype.IsChildOf = function(parent, child)
  485. {
  486. if (child == parent)
  487. {
  488. return false;
  489. }
  490. while (child && (child != document.body))
  491. {
  492. if (child == parent)
  493. {
  494. return true;
  495. }
  496. try
  497. {
  498. child = child.parentNode;
  499. }catch (e)
  500. {
  501. return false;
  502. }
  503. }
  504. return false;
  505. };
  506. RadMenu.prototype.OnDocumentClick = function(e)
  507. {
  508. var sourceElement = this.EventSource(e);
  509. if (this.IsChildOf(this.DomElement, sourceElement))
  510. {
  511. if (this.ClickToOpen)
  512. {
  513. return;
  514. }
  515. if (!this.IsChildOfMenuItem(sourceElement))
  516. {
  517. return;
  518. }
  519. }
  520. this.Hide();
  521. }
  522. RadMenu.prototype.IsChildOfMenuItem = function (element)
  523. {
  524. var tagName = element.tagName.toLowerCase();
  525. var className = element.className;
  526. if (tagName == "span" && className.indexOf("text") > -1)
  527. {
  528. return true;
  529. }
  530. if (tagName == "a" && className.indexOf("link") > -1)
  531. {
  532. return true;
  533. }
  534. if (tagName == "img" && className == "leftImage")
  535. {
  536. return true;
  537. }
  538. return false;
  539. }
  540. RadMenu.prototype.Enable = function ()
  541. {
  542. this.Enabled = true;
  543. this.DomElement.disabled = "";
  544. for (var i = 0; i < this.AllItems.length; i ++)
  545. {
  546. this.AllItems[i].Enable();
  547. }
  548. }
  549. RadMenu.prototype.Disable = function ()
  550. {
  551. this.Enabled = false;
  552. this.DomElement.disabled = "disabled";
  553. for (var i = 0; i < this.AllItems.length; i ++)
  554. {
  555. this.AllItems[i].Disable();
  556. }
  557. }
  558. RadMenu.prototype.Focus = function ()
  559. {
  560. this.DomElement.focus();
  561. }
  562. RadMenu.prototype.Dispose = function ()
  563. {
  564. if (this.Disposed)
  565. {
  566. return;
  567. }
  568. this.Disposed = true;
  569. for (var i = 0; i < this.AllItems.length; i ++)
  570. {
  571. this.AllItems[i].Dispose();
  572. }
  573. //TODO: Find the parent FORM
  574. if (this.Detached && this.DomElement)
  575. {
  576. if(this.DomElement.parentNode)
  577. {
  578. this.DomElement.parentNode.removeChild(this.DomElement);
  579. }
  580. }
  581. if (this.DomElement)
  582. {
  583. this.DomElement.RadShow = null;
  584. }
  585. this.DomElement = null;
  586. this.ChildItemList = null;
  587. this.StateField = null;
  588. this.DisposeDomEventHandlers();
  589. if (this.IsContext && RadMenuNamespace.ContextMenus)
  590. {
  591. RadMenuNamespace.ContextMenus[this.ID] = null;
  592. }
  593. }
  594. RadMenu.prototype.CreateMenuItem = function (parent, domElement)
  595. {
  596. var item = new RadMenuItem(domElement);
  597. this.AddItemToParent(parent, item);
  598. return item;
  599. };
  600. RadMenu.prototype.AddItemToParent = function(parent, item)
  601. {
  602. item.Index = parent.Items.length;
  603. parent.Items[parent.Items.length] = item;
  604. item.GlobalIndex = this.AllItems.length;
  605. this.AllItems[this.AllItems.length] = item;
  606. item.Parent = parent;
  607. item.Menu = this;
  608. }
  609. RadMenu.prototype.CreateControlHierarchy = function (parent, level)
  610. {
  611. parent.Level = level;
  612. var element = parent.ChildItemList;
  613. if (!element)
  614. {
  615. return;
  616. }
  617. for (var i = 0; i < element.childNodes.length; i ++)
  618. {
  619. var domNode = element.childNodes[i];
  620. if (domNode.nodeType == 3) continue;
  621. var item = this.CreateMenuItem(parent, domNode);
  622. item.Initialize();
  623. if (level == 0)
  624. {
  625. item.PostInitialize();
  626. }
  627. this.CreateControlHierarchy(item, level + 1);
  628. }
  629. };
  630. RadMenu.prototype.FixItemWidthInRTL = function ()
  631. {
  632. var maxWidth = 0;
  633. var maxItemWidth = 0;
  634. var ul = this.ChildItemList;
  635. for (var i = 0; i < ul.childNodes.length; i ++)
  636. {
  637. var li = ul.childNodes[i];
  638. if (li.nodeType == 3)
  639. continue;
  640. var element = RadMenu.GetFirstChildByTagName(li, "a");
  641. // Skip separators
  642. if (!element)
  643. {
  644. continue;
  645. }
  646. if (this.RightToLeft)
  647. {
  648. var image = element.getElementsByTagName("img")[0];
  649. if (image)
  650. {
  651. image.style.styleFloat = "left";
  652. }
  653. }
  654. maxWidth = Math.max(RadControlsNamespace.Box.GetOuterWidth(element), maxWidth);
  655. if (this.RightToLeft)
  656. {
  657. var image = element.getElementsByTagName("img")[0];
  658. if (image)
  659. {
  660. image.style.styleFloat = "right";
  661. }
  662. }
  663. }
  664. for (var i = 0; i < ul.childNodes.length; i ++)
  665. {
  666. var li = ul.childNodes[i];
  667. if (li.nodeType == 3) continue;
  668. if (RadControlsNamespace.Browser.IsOpera)
  669. {
  670. li.style.cssFloat = "none";
  671. }
  672. var a = RadMenu.GetFirstChildByTagName(li, "a");
  673. //Skip separators
  674. if (!a) continue;
  675. var imageOnly = !RadMenu.GetFirstChildByTagName(a, "span").firstChild;
  676. if (!RadControlsNamespace.Browser.IsIE || !imageOnly)
  677. {
  678. RadControlsNamespace.Box.SetOuterWidth(a, RadControlsNamespace.Box.GetOuterWidth(a));
  679. }
  680. }
  681. if (RadControlsNamespace.Browser.IsSafari)
  682. {
  683. ul.style.width = RadMenu.GetFirstChildByTagName(ul, "li").offsetWidth + "px";
  684. }
  685. };
  686. RadMenu.prototype.FixItemWidth = function (item)
  687. {
  688. var maxWidth = 0;
  689. var ul = item.ChildItemList;
  690. var widestItem = null;
  691. for (var i = 0; i < ul.childNodes.length; i ++)
  692. {
  693. var li = ul.childNodes[i];
  694. if (li.nodeType == 3)
  695. continue;
  696. var element = RadMenu.GetFirstChildByTagName(li, "a");
  697. if (!element)
  698. {
  699. element = RadMenu.GetFirstChildByTagName(li, "div");
  700. if (!element)
  701. {
  702. //Separator
  703. continue;
  704. }
  705. }
  706. if (this.RightToLeft)
  707. {
  708. var image = element.getElementsByTagName("img")[0];
  709. if (image)
  710. {
  711. image.style.styleFloat = "left";
  712. image.style.cssFloat = "left";
  713. }
  714. }
  715. var width = RadControlsNamespace.Box.GetOuterWidth(element);
  716. if (isNaN(width))
  717. {
  718. continue;
  719. }
  720. if (width > maxWidth)
  721. {
  722. maxWidth = width;
  723. widestItem = li;
  724. }
  725. if (this.RightToLeft)
  726. {
  727. var image = element.getElementsByTagName("img")[0];
  728. if (image)
  729. {
  730. image.style.styleFloat = "right";
  731. image.style.cssFloat = "right";
  732. }
  733. }
  734. }
  735. var calculatedMaxWidth = 0;
  736. for (var i = 0; i < ul.childNodes.length; i ++)
  737. {
  738. var li = ul.childNodes[i];
  739. if (li.nodeType == 3) continue;
  740. if (RadControlsNamespace.Browser.IsOpera)
  741. {
  742. li.style.cssFloat = "none";
  743. }
  744. var a = RadMenu.GetFirstChildByTagName(li, "a");
  745. if (a)
  746. {
  747. var imageOnly = !RadMenu.GetFirstChildByTagName(a, "span").firstChild;
  748. if (!RadControlsNamespace.Browser.IsIE || !imageOnly)
  749. {
  750. if (a.style.display != "none")
  751. {
  752. if (calculatedMaxWidth > 0)
  753. {
  754. a.style.width = calculatedMaxWidth + "px";
  755. }
  756. else
  757. {
  758. calculatedMaxWidth = RadControlsNamespace.Box.SetOuterWidth(a, maxWidth);
  759. }
  760. }
  761. }
  762. }
  763. else
  764. {
  765. li.style.width = maxWidth + "px";
  766. }
  767. }
  768. if (RadControlsNamespace.Browser.IsSafari)
  769. {
  770. if (widestItem)
  771. {
  772. ul.style.width = widestItem.offsetWidth + "px";
  773. }
  774. }
  775. };
  776. RadMenu.prototype.FixRootItemWidth = function()
  777. {
  778. var instance = this;
  779. var fixItemWidthClosure = function()
  780. {
  781. instance.FixItemWidth(instance);
  782. }
  783. if (this.RenderInProgress() || RadControlsNamespace.Browser.IsOpera || RadControlsNamespace.Browser.IsSafari)
  784. {
  785. if (window.addEventListener)
  786. {
  787. window.addEventListener('load', fixItemWidthClosure, false);
  788. }
  789. else
  790. {
  791. window.attachEvent('onload', fixItemWidthClosure);
  792. }
  793. }
  794. else
  795. {
  796. fixItemWidthClosure();
  797. }
  798. }
  799. RadMenu.prototype.FixListWidth = function (item)
  800. {
  801. if (this.RightToLeft)
  802. {
  803. this.FixItemWidth(item);
  804. }
  805. var totalWidth = 0;
  806. var ul = item.ChildItemList;
  807. for (var i = 0; i < ul.childNodes.length; i ++)
  808. {
  809. var node = ul.childNodes[i];
  810. if (node.nodeType == 3) continue;
  811. totalWidth += node.offsetWidth;
  812. // Additional
  813. node.style.clear = "none";
  814. }
  815. ul.style.width = totalWidth + "px";
  816. };
  817. RadMenu.prototype.LoadConfiguration = function (configObject)
  818. {
  819. for (var property in configObject)
  820. {
  821. this[property] = configObject[property];
  822. }
  823. if (!this.DefaultGroupSettings)
  824. {
  825. this.DefaultGroupSettings = {};
  826. }
  827. if (typeof this.DefaultGroupSettings.Flow == 'undefined')
  828. {
  829. this.DefaultGroupSettings.Flow = RadMenuNamespace.ItemFlow.Vertical;
  830. }
  831. if (typeof this.DefaultGroupSettings.ExpandDirection == 'undefined')
  832. {
  833. this.DefaultGroupSettings.ExpandDirection = RadMenuNamespace.ExpandDirection.Auto;
  834. }
  835. if (typeof this.DefaultGroupSettings.OffsetX == 'undefined')
  836. {
  837. this.DefaultGroupSettings.OffsetX = 0;
  838. }
  839. if (typeof this.DefaultGroupSettings.OffsetY == 'undefined')
  840. {
  841. this.DefaultGroupSettings.OffsetY = 0;
  842. }
  843. };
  844. RadMenu.prototype.Close = function (configObject)
  845. {
  846. if (this.OpenedItem)
  847. {
  848. this.OpenedItem.Close();
  849. }
  850. };
  851. RadMenu.prototype.FindItemByText = function(text)
  852. {
  853. for (var i = 0; i < this.AllItems.length; i++)
  854. {
  855. if (this.AllItems[i].Text == text)
  856. {
  857. return this.AllItems[i];
  858. }
  859. }
  860. return null;
  861. };
  862. RadMenu.prototype.FindItemById = function(id)
  863. {
  864. for (var i = 0; i < this.AllItems.length; i++)
  865. {
  866. if (this.AllItems[i].ID == id)
  867. {
  868. return this.AllItems[i];
  869. }
  870. }
  871. return null;
  872. };
  873. RadMenu.prototype.FindItemByValue = function(value)
  874. {
  875. for (var i = 0; i < this.AllItems.length; i++)
  876. {
  877. if (this.AllItems[i].Value == value)
  878. {
  879. return this.AllItems[i];
  880. }
  881. }
  882. return null;
  883. };
  884. RadMenu.prototype.FindItemByUrl = function(url)
  885. {
  886. for (var i = 0; i < this.AllItems.length; i++)
  887. {
  888. if (this.AllItems[i].NavigateUrl == url)
  889. {
  890. return this.AllItems[i];
  891. }
  892. }
  893. return null;
  894. };
  895. RadMenu.prototype.SetContextElementID = function (id)
  896. {
  897. if (!RadMenuNamespace.ContextElements)
  898. {
  899. RadMenuNamespace.ContextElements = {};
  900. }
  901. if (this.ContextMenuElementID)
  902. {
  903. RadMenuNamespace.ContextElements[this.ContextMenuElementID] = false;
  904. }
  905. this.ContextMenuElementID = id;
  906. RadMenuNamespace.ContextElements[this.ContextMenuElementID] = false;
  907. }
  908. RadMenu.prototype.RecordState = function ()
  909. {
  910. if (this.InUpdate || !this.Initialized)
  911. {
  912. return;
  913. }
  914. var state = RadControlsNamespace.JSON.stringify(this, this.InitialState, RadMenu.JSONIncludeDeep);
  915. var itemState = []
  916. for (var i in this.ItemState)
  917. {
  918. if (this.ItemState[i] == "") continue;
  919. if (typeof this.ItemState[i] == "function") continue;
  920. itemState[itemState.length] = this.ItemState[i];
  921. }
  922. this.StateField.value = "{\"State\":" + state + ",\"ItemState\":{" + itemState.join(",") + "}}";
  923. }
  924. RadMenu.prototype.PersistClientSideItems = function ()
  925. {
  926. for (var i = 0; i < this.AllItems.length; i++)
  927. {
  928. var item = this.AllItems[i];
  929. if (item.ClientSide)
  930. {
  931. item.RecordState(true);
  932. }
  933. }
  934. }
  935. RadMenu.prototype.SetAttribute = function (name, value)
  936. {
  937. this.Attributes[name] = value;
  938. this.RecordState();
  939. }
  940. RadMenu.prototype.GetAttribute = function (name)
  941. {
  942. return this.Attributes[name];
  943. }
  944. RadMenu.CreateChildItemContainer = function(parentItem)
  945. {
  946. var animationContainer = document.createElement("div");
  947. animationContainer.className = "slide";
  948. parentItem.DomElement.appendChild(animationContainer);
  949. var groupContainer = document.createElement("ul");
  950. if (parentItem.Flow == RadMenuNamespace.ItemFlow.Horizontal)
  951. {
  952. groupContainer.className = "horizontal group level" + parentItem.Level;
  953. }else
  954. {
  955. groupContainer.className = "vertical group level" + parentItem.Level;
  956. }
  957. animationContainer.appendChild(groupContainer);
  958. }
  959. RadMenu.prototype.AddItem = function(item)
  960. {
  961. var domElement = document.createElement("li");
  962. domElement.className = "item last";
  963. var linkElement = document.createElement("a");
  964. linkElement.className = "link";
  965. var textElement = document.createElement("span");
  966. textElement.className = "text";
  967. linkElement.appendChild(textElement);
  968. domElement.appendChild(linkElement);
  969. item.SetDomElement(domElement);
  970. var menu = this.Menu || this;
  971. if (menu != this && this.Items.length == 0)
  972. {
  973. RadMenu.CreateChildItemContainer(this);
  974. this.InitializeDomElements();
  975. this.InitializeAnimation();
  976. }
  977. this.ChildItemList.appendChild(domElement);
  978. menu.AddItemToParent(this, item);
  979. item.Level = this.Level + 1;
  980. var text = item.Text;
  981. item.Text = "";
  982. item.ID = this.ID + "_m" + (this.Items.length - 1);
  983. item.Initialize();
  984. item.SetText(text);
  985. if (this.Menu)
  986. {
  987. item.ParentClientID = this.ID;
  988. }
  989. linkElement.href = "#";
  990. if (this.Items.length > 1)
  991. {
  992. var previousDomElement = this.Items[this.Items.length - 2].DomElement;
  993. previousDomElement.className = previousDomElement.className.replace(" last", "");
  994. }
  995. }
  996. //BEGIN_ATLAS_NOTIFY
  997. if (typeof(Sys) != "undefined")
  998. {
  999. if (Sys.Application != null && Sys.Application.notifyScriptLoaded != null)
  1000. {
  1001. Sys.Application.notifyScriptLoaded();
  1002. }
  1003. }
  1004. //END_ATLAS_NOTIFY