RadMenuItem.js 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479
  1. function RadMenuItem(domElement)
  2. {
  3. if (domElement)
  4. {
  5. this.SetDomElement(domElement);
  6. }
  7. else
  8. {
  9. this.ClientSide = true;
  10. }
  11. this.IsSeparator = false;
  12. this.AnimationContainer = null;
  13. this.OpenedItem = null;
  14. this.FocusedItem = null;
  15. this.Items = [];
  16. this.Attributes = {};
  17. this.Index = -1;
  18. this.Level = -1;
  19. this.Parent = null;
  20. this.Menu = null;
  21. this.GroupSettings = {};
  22. this.TimeoutPointer = null;
  23. this.Templated = false;
  24. this.NavigateAfterClick = true;
  25. // css classes, load from the server
  26. this.FocusedCssClass = "focused";
  27. this.ClickedCssClass = "clicked";
  28. this.ExpandedCssClass = "expanded";
  29. this.DisabledCssClass = "disabled";
  30. this.CssClass = "";
  31. // state flags
  32. this.State = RadMenuItemState.Closed;
  33. this.Focused = false;
  34. this.Clicked = false;
  35. this.Enabled = true;
  36. this.Initialized = false;
  37. }
  38. RadMenuItem.prototype.SetDomElement = function(domElement)
  39. {
  40. this.DomElement = domElement;
  41. this.LinkElement = RadMenu.GetFirstChildByTagName(this.DomElement, "a");
  42. if (this.LinkElement == null)
  43. {
  44. this.ID = this.DomElement.id;
  45. this.TextElement = RadMenu.GetFirstChildByTagName(this.DomElement, "span");
  46. this.NavigateUrl = "";
  47. }
  48. else
  49. {
  50. this.ID = this.LinkElement.id;
  51. this.TextElement = RadMenu.GetFirstChildByTagName(this.LinkElement, "span");
  52. this.NavigateUrl = this.LinkElement.href;
  53. }
  54. }
  55. RadMenuItem.prototype.PostInitializeItems = function ()
  56. {
  57. for (var i = 0; i < this.Items.length; i ++)
  58. {
  59. this.Items[i].PostInitialize();
  60. }
  61. }
  62. RadMenuItem.prototype.SetText = function (text)
  63. {
  64. this.PostInitialize();
  65. this.TextElement.innerHTML = text;
  66. this.Text = text;
  67. this.RecordState();
  68. }
  69. RadMenuItem.prototype.SetNavigateUrl = function (url)
  70. {
  71. this.PostInitialize();
  72. this.LinkElement.setAttribute("href", url);
  73. this.NavigateUrl = url;
  74. this.RecordState();
  75. }
  76. RadMenuItem.prototype.SetValue = function (value)
  77. {
  78. this.PostInitialize();
  79. this.Value = value;
  80. this.RecordState();
  81. }
  82. RadMenuItem.prototype.InitializeDomElements = function()
  83. {
  84. if (!this.Templated)
  85. {
  86. this.AnimationContainer = RadMenu.GetFirstChildByTagName(this.DomElement, "div");
  87. this.ImageElement = RadMenu.GetFirstChildByTagName(this.LinkElement || this.DomElement, "img");
  88. if (this.ImageElement)
  89. {
  90. this.ImageUrl = this.ImageElement.src;
  91. }
  92. }
  93. else
  94. {
  95. this.TextElement = RadMenu.GetFirstChildByTagName(this.DomElement, "div");
  96. this.AnimationContainer = this.TextElement.nextSibling;
  97. }
  98. if (this.AnimationContainer)
  99. {
  100. var ul = this.AnimationContainer.getElementsByTagName("ul")[0];
  101. this.ChildItemList = ul;
  102. if (this.ChildItemList.parentNode != this.AnimationContainer)
  103. {
  104. this.ScrollWrap = this.ChildItemList.parentNode;
  105. }
  106. }
  107. }
  108. RadMenuItem.prototype.InitializeAnimation = function()
  109. {
  110. this.DetermineExpandDirection();
  111. if (!this.AnimationContainer)
  112. {
  113. return;
  114. }
  115. this.Ease = new RadControlsNamespace.Ease(
  116. this.ScrollWrap || this.ChildItemList,
  117. this.Menu,
  118. this.GroupSettings.OffsetX,
  119. this.GroupSettings.OffsetY,
  120. this,
  121. true
  122. );
  123. if (this.Ease.Overlay.Shim && this.LinkElement)
  124. {
  125. this.Ease.Overlay.Shim.id = this.LinkElement.id + "IframeOverlay";
  126. }
  127. var expandDirection = this.GroupSettings.ExpandDirection;
  128. var easeProperty = RadMenuNamespace.ExpandDirectionPropertyName[expandDirection];
  129. this.Ease.SetSide(easeProperty);
  130. this.TextElement.className = "text expand" + this.Ease.GetSide();
  131. this.AnimationContainer.style.zIndex = this.GlobalIndex + 10;
  132. this.ChildItemList.style.zIndex = this.GlobalIndex + 10;
  133. if (this.ScrollWrap)
  134. {
  135. this.CreateScroll();
  136. }
  137. }
  138. RadMenuItem.prototype.Initialize = function ()
  139. {
  140. RadControlsNamespace.DomEventMixin.Initialize(this);
  141. this.LoadConfiguration();
  142. this.InitializeDomElements();
  143. if (this.TextElement && this.TextElement.firstChild)
  144. {
  145. this.Text = this.TextElement.firstChild.nodeValue;
  146. }
  147. this.OriginalZIndex = Math.max(this.DomElement.style.zIndex, this.Menu.OriginalZIndex);
  148. };
  149. RadMenuItem.prototype.PostInitialize = function ()
  150. {
  151. if (this.Initialized)
  152. {
  153. return;
  154. }
  155. this.InitializeAnimation();
  156. this.AttachEventHandlers();
  157. this.RenderAccessKey();
  158. RadMenu.CreateState(this);
  159. this.UpdateCssClass();
  160. this.Initialized = true;
  161. }
  162. RadMenuItem.prototype.RenderAccessKey = function ()
  163. {
  164. if (this.IsSeparator || this.Templated)
  165. {
  166. return;
  167. }
  168. var accessKey = this.LinkElement.accessKey.toLowerCase();
  169. // If accessKey is not set
  170. if (!accessKey)
  171. {
  172. return;
  173. }
  174. var text = this.TextElement.firstChild.nodeValue;
  175. var indexOfAccessKey = text.toLowerCase().indexOf(accessKey);
  176. // If accesKey is not found
  177. if (indexOfAccessKey == -1)
  178. {
  179. return;
  180. }
  181. this.TextElement.innerHTML =
  182. text.substr(0, indexOfAccessKey) +
  183. "<u>" +
  184. text.substr(indexOfAccessKey, 1) +
  185. "</u>" +
  186. text.substr(indexOfAccessKey + 1, text.length);
  187. }
  188. RadMenuItem.prototype.CreateScroll = function ()
  189. {
  190. this.ScrollWrap.style.zIndex = this.GlobalIndex + 10;
  191. this.BuildScrollObject(false);
  192. }
  193. RadMenuItem.prototype.BuildScrollObject = function (wrapNeeded)
  194. {
  195. var isVertical = RadMenuNamespace.ItemFlow.Vertical == this.GroupSettings.Flow;
  196. var options = {PerTabScrolling : false, ScrollButtonsPosition : 1, ScrollPosition : 0};
  197. this.Scroll = new RadControlsNamespace.Scroll(this.ChildItemList, isVertical, options);
  198. this.Scroll.ScrollOnHover = true;
  199. this.Scroll.LeaveGapsForArrows = false;
  200. this.Scroll.WrapNeeded = wrapNeeded;
  201. if (this.GroupSettings.Flow == RadMenuNamespace.ItemFlow.Vertical)
  202. {
  203. this.Scroll.LeftArrowClass = "topArrow";
  204. this.Scroll.LeftArrowClassDisabled = "topArrowDisabled";
  205. this.Scroll.RightArrowClass = "bottomArrow";
  206. this.Scroll.RightArrowClassDisabled = "bottomArrowDisabled";
  207. }
  208. }
  209. RadMenuItem.prototype.CreateRuntimeScroll = function (height)
  210. {
  211. if (this.Scroll)
  212. {
  213. this.Scroll.SetHeight(height);
  214. return;
  215. }
  216. this.BuildScrollObject(true);
  217. this.Scroll.Initialize()
  218. this.ScrollWrap = this.ChildItemList.parentNode;
  219. this.Ease.Element = this.ScrollWrap;
  220. this.Ease.Overlay.Element = this.ScrollWrap;
  221. this.ScrollWrap.className = "scrollWrap " + this.ChildItemList.className;
  222. this.ChildItemList.className = this.ChildItemList.className.replace("group", "");
  223. this.Scroll.SetHeight(height);
  224. }
  225. RadMenuItem.prototype.Dispose = function ()
  226. {
  227. if (!this.Initialized) return;
  228. this.DisposeDomEventHandlers();
  229. if (this.Ease)
  230. {
  231. this.Ease.Dispose();
  232. }
  233. this.DomElement = null;
  234. this.LinkElement = null;
  235. this.AnimationContainer = null;
  236. }
  237. RadMenuItem.prototype.Focus = function ()
  238. {
  239. if (!this.CanFocus())
  240. {
  241. return;
  242. }
  243. this.PostInitializeItems();
  244. if (this.Parent.OpenedItem && this.Parent.OpenedItem != this)
  245. {
  246. this.Parent.OpenedItem.Close();
  247. }
  248. if (this.Parent.State != RadMenuItemState.Open && this.Parent.Open)
  249. {
  250. this.Parent.Open();
  251. }
  252. this.Parent.FocusedItem = this;
  253. if (!this.Focused && this.LinkElement)
  254. {
  255. this.LinkElement.focus();
  256. }
  257. this.UpdateCssClass();
  258. this.RaiseEvent("OnClientItemFocus");
  259. }
  260. RadMenuItem.prototype.Hide = function()
  261. {
  262. if (this.LinkElement)
  263. {
  264. this.LinkElement.style.display = "none";
  265. }
  266. else
  267. {
  268. this.TextElement.style.display = "none";
  269. }
  270. if (this.Parent.Flow == RadMenuNamespace.ItemFlow.Vertical)
  271. {
  272. var siblings = this.Parent.Items;
  273. for (var i = 0; i < siblings.length; i++)
  274. {
  275. if (siblings[i] != this)
  276. {
  277. if (siblings[i].LinkElement)
  278. {
  279. siblings[i].LinkElement.style.width = "auto";
  280. }
  281. }
  282. }
  283. if (RadControlsNamespace.Browser.IsSafari)
  284. {
  285. this.Parent.ChildItemList.style.width = "auto";
  286. }
  287. this.Menu.WidthFixed = false;
  288. if (this.Parent.DomElement.offsetWidth > 0)
  289. {
  290. this.Menu.FixItemWidth(this.Parent);
  291. }
  292. }
  293. }
  294. RadMenuItem.prototype.IsVisible = function()
  295. {
  296. if (!this.LinkElement)
  297. {
  298. return this.TextElement.style.display != "none";
  299. }
  300. return this.LinkElement.style.display != "none";
  301. }
  302. RadMenuItem.prototype.Show = function()
  303. {
  304. if (this.LinkElement)
  305. {
  306. this.LinkElement.style.display = "";
  307. }
  308. else
  309. {
  310. this.TextElement.style.display = "";
  311. }
  312. if (this.Parent.Flow == RadMenuNamespace.ItemFlow.Vertical)
  313. {
  314. this.Menu.WidthFixed = false;
  315. if (this.Parent.DomElement.offsetWidth > 0)
  316. {
  317. this.Menu.FixItemWidth(this.Parent);
  318. }
  319. }
  320. }
  321. RadMenuItem.prototype.Blur = function ()
  322. {
  323. if (this.IsSeparator)
  324. {
  325. return;
  326. }
  327. if (this.Focused)
  328. {
  329. this.LinkElement.blur();
  330. }
  331. this.Parent.FocusedItem = null;
  332. this.UpdateCssClass();
  333. this.RaiseEvent("OnClientItemBlur");
  334. }
  335. RadMenuItem.prototype.GetEaseSide = function ()
  336. {
  337. var expandDirection = this.GroupSettings.ExpandDirection;
  338. return RadMenuNamespace.ExpandDirectionPropertyName[expandDirection];
  339. }
  340. RadMenuItem.prototype.RaiseEvent = function(eventName)
  341. {
  342. return this.Menu.RaiseEvent(eventName, {Item:this});
  343. }
  344. RadMenuItem.prototype.UpdateCssClass = function ()
  345. {
  346. if (this.IsSeparator || this.Templated)
  347. {
  348. return;
  349. }
  350. var cssClass = "link " + this.CssClass;
  351. if (this.Focused)
  352. {
  353. cssClass = cssClass + " " + this.FocusedCssClass;
  354. }
  355. if (this.State == RadMenuItemState.Open)
  356. {
  357. cssClass = cssClass + " " + this.ExpandedCssClass;
  358. }
  359. if (this.Clicked)
  360. {
  361. cssClass = cssClass + " " + this.ClickedCssClass;
  362. }
  363. if (!this.Enabled)
  364. {
  365. cssClass = cssClass + " " + this.DisabledCssClass;
  366. }
  367. this.LinkElement.className = cssClass;
  368. this.UpdateImageUrl();
  369. }
  370. RadMenuItem.prototype.UpdateImageUrl = function ()
  371. {
  372. if (!this.ImageElement) return;
  373. var newUrl = this.ImageUrl;
  374. if (this.Hovered && this.ImageOverUrl)
  375. {
  376. newUrl = this.ImageOverUrl;
  377. }
  378. if (this.State == RadMenuItemState.Open && this.ExpandedImageUrl)
  379. {
  380. newUrl = this.ExpandedImageUrl;
  381. }
  382. if (!this.Enabled && this.DisabledImageUrl)
  383. {
  384. newUrl = this.DisabledImageUrl;
  385. }
  386. if (this.Clicked && this.ImageClickedUrl)
  387. {
  388. newUrl = this.ImageClickedUrl;
  389. }
  390. newUrl = newUrl.replace(/&amp;/ig, "&");
  391. if (newUrl != this.ImageElement.src)
  392. {
  393. this.ImageElement.src = newUrl;
  394. }
  395. }
  396. RadMenuItem.prototype.Enable = function ()
  397. {
  398. if (this.IsSeparator || this.Templated)
  399. {
  400. return;
  401. }
  402. this.LinkElement.disabled = "";
  403. if (this.ImageElement)
  404. {
  405. this.ImageElement.disabled = "";
  406. }
  407. this.Enabled = true;
  408. this.EnableDomEventHandling();
  409. this.UpdateCssClass();
  410. }
  411. RadMenuItem.prototype.Disable = function ()
  412. {
  413. if (this.IsSeparator || this.Templated)
  414. {
  415. return;
  416. }
  417. this.LinkElement.disabled = "disabled";
  418. if (this.ImageElement)
  419. {
  420. this.ImageElement.disabled = "disabled";
  421. }
  422. this.Enabled = false;
  423. this.DisableDomEventHandling();
  424. this.UpdateCssClass();
  425. }
  426. RadMenuItem.prototype.OnCollapseComplete = function()
  427. {
  428. this.RaiseEvent("OnClientItemClose");
  429. }
  430. RadMenuItem.prototype.HideChildren = function ()
  431. {
  432. for (var i = 0; i < this.Items.length; i++)
  433. {
  434. if (this.Items[i].AnimationContainer)
  435. {
  436. this.Items[i].AnimationContainer.style.display = "none";
  437. }
  438. }
  439. }
  440. RadMenuItem.prototype.CalculateScrollWrapSize = function ()
  441. {
  442. if (!this.ScrollWrap)
  443. {
  444. return;
  445. }
  446. if (!this.ScrollWrap.style.height)
  447. {
  448. this.ScrollWrap.style.height = this.ChildItemList.offsetHeight + "px";
  449. }
  450. var isVertical = RadMenuNamespace.ItemFlow.Vertical == this.Flow;
  451. if (isVertical)
  452. {
  453. this.ScrollWrap.style.width = this.ChildItemList.offsetWidth + "px";
  454. }
  455. };
  456. RadMenuItem.prototype.OnEase = function(newValue)
  457. {
  458. var isVertical = RadMenuNamespace.ItemFlow.Vertical == this.Flow;
  459. if (!isVertical) return;
  460. if (this.ChildrenDetached && this.Scroll)
  461. {
  462. //Hack for IE6 - arrows disappear after scrolling
  463. this.Scroll.RightArrow.style.cssText = this.Scroll.RightArrow.style.cssText;
  464. this.Scroll.LeftArrow.style.cssText = this.Scroll.LeftArrow.style.cssText;
  465. }
  466. }
  467. /**
  468. * Event handlers
  469. */
  470. RadMenuItem.prototype.AttachEventHandlers = function ()
  471. {
  472. this.AttachDomEvent(this.DomElement, "mouseover", "MouseOverHandler");
  473. this.AttachDomEvent(this.DomElement, "mouseout", "MouseOutHandler");
  474. if (this.IsSeparator || this.Templated)
  475. {
  476. return;
  477. }
  478. this.AttachDomEvent(this.LinkElement, "click", "ClickHandler", true);
  479. this.AttachDomEvent(this.LinkElement, "mouseout", "HRefMouseOutHandler");
  480. this.AttachDomEvent(this.LinkElement, "mouseover", "HRefMouseOverHandler");
  481. this.AttachDomEvent(this.LinkElement, "mousedown", "MouseDownHandler");
  482. this.AttachDomEvent(this.LinkElement, "mouseup", "MouseUpHandler");
  483. this.AttachDomEvent(this.LinkElement, "blur", "BlurHandler");
  484. this.AttachDomEvent(this.LinkElement, "focus", "FocusHandler");
  485. this.AttachDomEvent(this.LinkElement, "keydown", "KeyDownHandler");
  486. };
  487. RadMenuItem.prototype.MouseDownHandler = function (e)
  488. {
  489. this.Clicked = true;
  490. this.UpdateCssClass();
  491. }
  492. RadMenuItem.prototype.MouseUpHandler = function (e)
  493. {
  494. this.Clicked = false;
  495. this.UpdateCssClass();
  496. }
  497. RadMenuItem.prototype.HRefMouseOutHandler = function (e)
  498. {
  499. var to = RadControlsNamespace.DomEvent.GetRelatedTarget(e);
  500. if (this.Menu.IsChildOf(this.LinkElement, to) || to == this.LinkElement)
  501. {
  502. return;
  503. }
  504. this.Hovered = false;
  505. this.UpdateImageUrl();
  506. this.RaiseEvent("OnClientMouseOut");
  507. }
  508. RadMenuItem.prototype.HRefMouseOverHandler = function (e)
  509. {
  510. var from = RadControlsNamespace.DomEvent.GetRelatedTarget(e);
  511. if (this.Menu.IsChildOf(this.LinkElement, from) || this.LinkElement == from)
  512. {
  513. return;
  514. }
  515. this.Hovered = true;
  516. this.UpdateImageUrl();
  517. this.RaiseEvent("OnClientMouseOver");
  518. }
  519. RadMenuItem.prototype.KeyDownHandler = function (e)
  520. {
  521. var arrows = {left : 37, up : 38, right : 39, down : 40, esc : 27 };
  522. var keyCode = RadControlsNamespace.DomEvent.GetKeyCode(e);
  523. if (keyCode == arrows.right)
  524. {
  525. if (this.Menu.RightToLeft)
  526. {
  527. this.HandleLeftArrow();
  528. }
  529. else
  530. {
  531. this.HandleRightArrow();
  532. }
  533. }
  534. else if (keyCode == arrows.left)
  535. {
  536. if (this.Menu.RightToLeft)
  537. {
  538. this.HandleRightArrow();
  539. }
  540. else
  541. {
  542. this.HandleLeftArrow();
  543. }
  544. }
  545. else if (keyCode == arrows.up)
  546. {
  547. this.HandleUpArrow();
  548. }
  549. else if (keyCode == arrows.down)
  550. {
  551. this.HandleDownArrow();
  552. }
  553. else if (keyCode == arrows.esc)
  554. {
  555. if (this.Parent == this.Menu)
  556. {
  557. this.Blur();
  558. }
  559. else
  560. {
  561. this.Parent.Close();
  562. this.Parent.Focus();
  563. }
  564. }
  565. else
  566. {
  567. return;
  568. }
  569. RadControlsNamespace.DomEvent.PreventDefault(e);
  570. }
  571. RadMenuItem.prototype.FocusHandler = function (e)
  572. {
  573. this.Focused = true;
  574. this.Focus();
  575. }
  576. RadMenuItem.prototype.BlurHandler = function (e)
  577. {
  578. this.Focused = false;
  579. //Korchev: Causes problem when second level item is clicked - the item cannot be open after that
  580. //this.Menu.Clicked = false;
  581. this.Blur();
  582. }
  583. RadMenuItem.prototype.NavigatesToURL = function ()
  584. {
  585. if (location.href + "#" == this.NavigateUrl || location.href == this.NavigateUrl)
  586. {
  587. return false;
  588. }
  589. return (new RegExp("//")).test(this.LinkElement.href);
  590. }
  591. RadMenuItem.prototype.Validate = function ()
  592. {
  593. if (!this.Menu.CausesValidation || this.NavigatesToURL())
  594. {
  595. return true;
  596. }
  597. if (typeof (Page_ClientValidate) != 'function')
  598. {
  599. return true;
  600. }
  601. return Page_ClientValidate(this.Menu.ValidationGroup);
  602. }
  603. RadMenuItem.prototype.ClickHandler = function (e)
  604. {
  605. if (!this.Enabled)
  606. {
  607. return RadControlsNamespace.DomEvent.PreventDefault(e);
  608. }
  609. if (!this.RaiseEvent("OnClientItemClicking"))
  610. {
  611. return RadControlsNamespace.DomEvent.PreventDefault(e);
  612. }
  613. if (!this.Validate())
  614. {
  615. return RadControlsNamespace.DomEvent.PreventDefault(e);
  616. }
  617. var returnValue = true;
  618. if (!this.Menu.ClickToOpen)
  619. {
  620. returnValue = true;
  621. }
  622. else if (this.Level > 1) // only first level items toggle this
  623. {
  624. returnValue = true;
  625. }
  626. else
  627. {
  628. if (!this.Menu.Clicked)
  629. {
  630. this.Open();
  631. }
  632. else
  633. {
  634. this.Close();
  635. }
  636. this.Menu.Clicked = !this.Menu.Clicked;
  637. }
  638. this.RaiseEvent("OnClientItemClicked");
  639. if (!this.NavigateAfterClick || !returnValue)
  640. {
  641. RadControlsNamespace.DomEvent.PreventDefault(e);
  642. }
  643. }
  644. RadMenuItem.prototype.PreventClose = function()
  645. {
  646. if (this.State == RadMenuItemState.AboutToClose)
  647. {
  648. this.ClearTimeout();
  649. this.State = RadMenuItemState.Open;
  650. this.Parent.OpenedItem = this;
  651. }
  652. if (this.Parent.PreventClose)
  653. {
  654. this.Parent.PreventClose();
  655. }
  656. }
  657. RadMenuItem.prototype.Open = function ()
  658. {
  659. this.PostInitializeItems();
  660. this.Menu.AboutToCollapse = false;
  661. if (this.Parent != this.Menu && this.Parent.State != RadMenuItemState.Open)
  662. {
  663. this.Parent.Open();
  664. }
  665. if (!this.AnimationContainer) return;
  666. this.Parent.OpenedItem = this;
  667. this.State = RadMenuItemState.Open;
  668. var documentSize = RadControlsNamespace.Screen.GetViewPortSize();
  669. this.ChildItemList.style.display = "block";
  670. this.Ease.ShowElements();
  671. if (this.GroupSettings.Flow == RadMenuNamespace.ItemFlow.Vertical)
  672. {
  673. this.Menu.FixItemWidth(this);
  674. }
  675. else
  676. {
  677. this.Menu.FixListWidth(this);
  678. }
  679. if (this.Menu.EnableAutoScroll && this.ChildItemList.offsetHeight > documentSize.height)
  680. {
  681. if (!this.ScrollWrap || this.ScrollWrap.offsetHeight > documentSize.height)
  682. {
  683. this.CreateRuntimeScroll(documentSize.height + "px");
  684. this.Ease.ShowElements();
  685. this.Ease.UpdateContainerSize();
  686. }
  687. }
  688. this.Ease.SetSide(this.GetEaseSide());
  689. this.Ease.UpdateContainerSize();
  690. if (this.Scroll)
  691. {
  692. this.CalculateScrollWrapSize();
  693. this.Scroll.Initialize();
  694. }
  695. this.PositionChildContainer(documentSize);
  696. this.Ease.In();
  697. this.UpdateCssClass();
  698. this.DomElement.style.zIndex = this.OriginalZIndex + 1000;
  699. if (!RadControlsNamespace.Browser.IsNetscape)
  700. {
  701. this.Menu.DomElement.style.zIndex = this.Menu.OriginalZIndex + 1000;
  702. }
  703. this.RaiseEvent("OnClientItemOpen");
  704. };
  705. RadMenuItem.prototype.MouseOverHandler = function (e)
  706. {
  707. this.PreventClose();
  708. if (this.Menu.ClickToOpen && !this.Menu.Clicked)
  709. {
  710. return;
  711. }
  712. if (this.State == RadMenuItemState.Open || this.State == RadMenuItemState.AboutToOpen)
  713. {
  714. return;
  715. }
  716. if (this.Parent.OpenedItem != this && this.Parent.OpenedItem)
  717. {
  718. var openedItem = this.Parent.OpenedItem;
  719. if (openedItem.TimeoutPointer)
  720. {
  721. openedItem.ClearTimeout();
  722. }
  723. openedItem.State = RadMenuItemState.AboutToClose;
  724. openedItem.SetTimeout(function() {
  725. openedItem.Close();
  726. openedItem.TimeoutPointer = null;
  727. }, this.Menu.ExpandDelay);
  728. }
  729. if (this.Items.length < 1)
  730. return;
  731. this.Menu.LastOpenedItem = this;
  732. this.State = RadMenuItemState.AboutToOpen;
  733. var instance = this;
  734. this.SetTimeout(function () {
  735. instance.Open();
  736. instance.TimeoutPointer = null;
  737. }, this.Menu.ExpandDelay);
  738. }
  739. RadMenuItem.prototype.Close = function ()
  740. {
  741. if (this.IsSeparator)
  742. {
  743. return;
  744. }
  745. if (this.State == RadMenuItemState.Closed)
  746. {
  747. return;
  748. }
  749. if (this.OpenedItem)
  750. {
  751. this.OpenedItem.Close();
  752. }
  753. this.Parent.OpenedItem = null;
  754. if (!this.AnimationContainer) return;
  755. this.State = RadMenuItemState.Closed;
  756. if (this.Level == 1)
  757. {
  758. this.Menu.AboutToCollapse = true;
  759. }
  760. this.Ease.Out();
  761. this.UpdateCssClass();
  762. this.DomElement.style.zIndex = this.OriginalZIndex;
  763. if (!RadControlsNamespace.Browser.IsNetscape)
  764. {
  765. if (this.Level == 1)
  766. {
  767. this.Menu.DomElement.style.zIndex = this.Menu.OriginalZIndex;
  768. }
  769. }
  770. this.HideChildren ();
  771. }
  772. RadMenuItem.prototype.MouseOutHandler = function (e)
  773. {
  774. var to = RadControlsNamespace.DomEvent.GetRelatedTarget(e);
  775. if ((!to) || this.Menu.IsChildOf(this.DomElement, to) || to == this.DomElement)
  776. {
  777. return;
  778. }
  779. if (this.ChildrenDetached)
  780. {
  781. if (this.Menu.IsChildOf(this.Parent.AnimationContainer, to))
  782. {
  783. return;
  784. }
  785. }
  786. try
  787. {
  788. //Fix FireFox "_moz_editor_bogus_node" problem.
  789. var bogusNode = to.parentNode;
  790. }catch (e)
  791. {
  792. return;
  793. }
  794. if (this.State == RadMenuItemState.Closed || this.State == RadMenuItemState.AboutToClose)
  795. {
  796. return;
  797. }
  798. if (this.State == RadMenuItemState.AboutToOpen)
  799. {
  800. this.ClearTimeout();
  801. this.State = RadMenuItemState.Closed;
  802. this.Parent.OpenedItem = null;
  803. return;
  804. }
  805. if (this.Menu.ClickToOpen)
  806. {
  807. return;
  808. }
  809. this.State = RadMenuItemState.AboutToClose;
  810. var instance = this;
  811. this.SetTimeout(function () {
  812. instance.Close();
  813. instance.TimeoutPointer = null;
  814. }, this.Menu.CollapseDelay);
  815. }
  816. RadMenuItem.prototype.SetTimeout = function (closure, delay)
  817. {
  818. this.TimeoutPointer = setTimeout(closure, delay);
  819. }
  820. RadMenuItem.prototype.ClearTimeout = function()
  821. {
  822. if (this.TimeoutPointer)
  823. {
  824. clearTimeout(this.TimeoutPointer);
  825. this.TimeoutPointer = null;
  826. }
  827. }
  828. RadMenuItem.prototype.PositionChildContainer = function (documentSize)
  829. {
  830. var top = 0;
  831. var left = 0;
  832. var expandDirection = this.GroupSettings.ExpandDirection;
  833. var easeProperty = RadMenuNamespace.ExpandDirectionPropertyName[expandDirection];
  834. var ownerBox = this.DomElement;
  835. var itemHeight = RadControlsNamespace.Box.GetOuterHeight(ownerBox);
  836. var itemWidth = RadControlsNamespace.Box.GetOuterWidth(ownerBox);
  837. var itemBox = this.AnimationContainer;
  838. //itemBox.style.border = "1px solid red";
  839. var childItemsHeight = RadControlsNamespace.Box.GetOuterHeight(itemBox);
  840. var childItemsWidth = RadControlsNamespace.Box.GetOuterWidth(itemBox);
  841. if (expandDirection == RadMenuNamespace.ExpandDirection.Down)
  842. {
  843. top = itemHeight;
  844. }
  845. else if (expandDirection == RadMenuNamespace.ExpandDirection.Right)
  846. {
  847. left = itemWidth;
  848. }
  849. this.SetContainerPosition(left, top);
  850. var childItemsPosition = RadControlsNamespace.Screen.GetElementPosition(itemBox);
  851. if (this.Menu.RightToLeft)
  852. {
  853. left = itemWidth - childItemsWidth;
  854. }
  855. if (!this.Menu.EnableScreenBoundaryDetection)
  856. {
  857. this.Ease.SetSide(easeProperty);
  858. this.TextElement.className = "text expand" + this.Ease.GetSide();
  859. return;
  860. }
  861. // Screen boundary detection
  862. if (
  863. RadControlsNamespace.Screen.ElementOverflowsRight(documentSize, itemBox) &&
  864. expandDirection == RadMenuNamespace.ExpandDirection.Right
  865. )
  866. {
  867. expandDirection = RadMenuNamespace.ExpandDirection.Left;
  868. easeProperty = "right";
  869. left = 0;
  870. }
  871. else if (childItemsPosition.x - childItemsWidth < 0 && expandDirection == RadMenuNamespace.ExpandDirection.Left)
  872. {
  873. expandDirection = RadMenuNamespace.ExpandDirection.Right;
  874. easeProperty = "left";
  875. left = itemWidth;
  876. }
  877. else if (childItemsPosition.y - childItemsHeight < 0 && expandDirection == RadMenuNamespace.ExpandDirection.Up)
  878. {
  879. expandDirection = RadMenuNamespace.ExpandDirection.Down;
  880. easeProperty = "top";
  881. top = itemHeight;
  882. }
  883. else if (
  884. RadControlsNamespace.Screen.ElementOverflowsBottom(documentSize, itemBox) &&
  885. expandDirection == RadMenuNamespace.ExpandDirection.Down
  886. )
  887. {
  888. //Check if there is enough space to invert the expand direction
  889. var itemBox = RadControlsNamespace.Screen.GetElementPosition(this.DomElement);
  890. if (itemBox.y > this.AnimationContainer.offsetHeight)
  891. {
  892. expandDirection = RadMenuNamespace.ExpandDirection.Up;
  893. easeProperty = "bottom";
  894. top = itemHeight;
  895. }
  896. }
  897. // Side offset
  898. if ( RadControlsNamespace.Screen.ElementOverflowsRight(documentSize, itemBox) &&
  899. (expandDirection == RadMenuNamespace.ExpandDirection.Down ||
  900. expandDirection == RadMenuNamespace.ExpandDirection.Up)
  901. )
  902. {
  903. if (!this.Menu.RightToLeft)
  904. {
  905. left = documentSize.width - (childItemsPosition.x + childItemsWidth);
  906. }
  907. }
  908. else if (RadControlsNamespace.Screen.ElementOverflowsBottom(documentSize, itemBox))
  909. {
  910. if (expandDirection == RadMenuNamespace.ExpandDirection.Left ||
  911. expandDirection == RadMenuNamespace.ExpandDirection.Right)
  912. {
  913. top = documentSize.height - (childItemsPosition.y + childItemsHeight);
  914. //alert(top);
  915. }
  916. }
  917. this.SetContainerPosition(left, top);
  918. this.Ease.SetSide(easeProperty);
  919. this.TextElement.className = "text expand" + this.Ease.GetSide();
  920. };
  921. RadMenuItem.prototype.SetContainerPosition = function(left, top)
  922. {
  923. var y = top + this.GroupSettings.OffsetY;
  924. if (this.Parent.ScrollWrap)
  925. {
  926. if (this.Parent == this.Menu && this.Menu.IsContext)
  927. {
  928. this.Parent.AnimationContainer = this.Menu.DomElement;
  929. }
  930. if (this.Parent.AnimationContainer)
  931. {
  932. this.ChildrenDetached = true;
  933. this.Parent.AnimationContainer.appendChild(this.AnimationContainer);
  934. }
  935. y += this.DomElement.offsetTop;
  936. var childListTop = parseInt(this.Parent.ChildItemList.style.top);
  937. if (isNaN(childListTop))
  938. {
  939. childListTop = 0;
  940. }
  941. if (this.GroupSettings.OffsetY == 0)
  942. {
  943. // Compensate for the scroll offset only if there is no group offset Y set.
  944. y += childListTop;
  945. }
  946. }
  947. this.AnimationContainer.style.top = y + "px";
  948. this.AnimationContainer.style.left = (left + this.GroupSettings.OffsetX) + "px";
  949. }
  950. RadMenuItem.prototype.SetAttribute = function (name, value)
  951. {
  952. this.PostInitialize();
  953. this.Attributes[name] = value;
  954. this.RecordState();
  955. }
  956. RadMenuItem.prototype.SetImageUrl = function (src)
  957. {
  958. this.PostInitialize();
  959. this.ImageUrl = src;
  960. this.ImageElement.src = src;
  961. this.RecordState();
  962. }
  963. RadMenuItem.prototype.SetImageOverUrl = function (src)
  964. {
  965. this.PostInitialize();
  966. this.ImageOverUrl = src;
  967. this.RecordState();
  968. }
  969. RadMenuItem.prototype.GetAttribute = function (name)
  970. {
  971. return this.Attributes[name];
  972. }
  973. RadMenuItem.prototype.DetermineExpandDirection = function ()
  974. {
  975. if (this.GroupSettings.ExpandDirection != RadMenuNamespace.ExpandDirection.Auto)
  976. {
  977. return;
  978. }
  979. if (this.Parent.Flow == RadMenuNamespace.ItemFlow.Vertical)
  980. {
  981. if (this.Menu.RightToLeft)
  982. {
  983. this.GroupSettings.ExpandDirection = RadMenuNamespace.ExpandDirection.Left;
  984. }
  985. else
  986. {
  987. this.GroupSettings.ExpandDirection = RadMenuNamespace.ExpandDirection.Right;
  988. }
  989. }
  990. else
  991. {
  992. this.GroupSettings.ExpandDirection = RadMenuNamespace.ExpandDirection.Down;
  993. }
  994. }
  995. RadMenuItem.prototype.LoadConfiguration = function ()
  996. {
  997. if (this.Menu.ItemData[this.ID])
  998. {
  999. for (var property in this.Menu.ItemData[this.ID])
  1000. {
  1001. this[property] = this.Menu.ItemData[this.ID][property];
  1002. }
  1003. }
  1004. var defaultSettings = this.Menu.DefaultGroupSettings;
  1005. // default settings for nested config objects
  1006. if (typeof this.GroupSettings.Flow == 'undefined')
  1007. {
  1008. this.GroupSettings.Flow = defaultSettings.Flow;
  1009. }
  1010. this.Flow = this.GroupSettings.Flow;
  1011. if (typeof this.GroupSettings.ExpandDirection == 'undefined')
  1012. {
  1013. this.GroupSettings.ExpandDirection = defaultSettings.ExpandDirection;
  1014. }
  1015. if (typeof this.GroupSettings.OffsetX == 'undefined')
  1016. {
  1017. this.GroupSettings.OffsetX = defaultSettings.OffsetX;
  1018. }
  1019. if (typeof this.GroupSettings.OffsetY == 'undefined')
  1020. {
  1021. this.GroupSettings.OffsetY = defaultSettings.OffsetY;
  1022. }
  1023. if (!this.Enabled)
  1024. {
  1025. this.Disable();
  1026. }
  1027. };
  1028. /**
  1029. * Keyboard handlers
  1030. */
  1031. RadMenuItem.prototype.HandleRightArrow = function ()
  1032. {
  1033. if (this.Parent.Flow == RadMenuNamespace.ItemFlow.Horizontal)
  1034. {
  1035. this.FocusNextItem();
  1036. }
  1037. else
  1038. {
  1039. if (this.Items.length && this.GroupSettings.ExpandDirection == RadMenuNamespace.ExpandDirection.Right)
  1040. {
  1041. this.FocusFirstChild();
  1042. }
  1043. else if (this.Parent.GroupSettings &&
  1044. this.Parent.GroupSettings.ExpandDirection == RadMenuNamespace.ExpandDirection.Left)
  1045. {
  1046. this.Parent.Focus();
  1047. }
  1048. else
  1049. {
  1050. if (this.Menu.OpenedItem)
  1051. {
  1052. this.Menu.OpenedItem.GetNextItem().Focus();
  1053. }
  1054. }
  1055. }
  1056. }
  1057. RadMenuItem.prototype.HandleLeftArrow = function ()
  1058. {
  1059. if (this.Parent.Flow == RadMenuNamespace.ItemFlow.Horizontal)
  1060. {
  1061. this.FocusPreviousItem();
  1062. }
  1063. else
  1064. {
  1065. if (this.Items.length && this.GroupSettings.ExpandDirection == RadMenuNamespace.ExpandDirection.Left)
  1066. {
  1067. this.FocusFirstChild();
  1068. }
  1069. else if (this.Parent.GroupSettings &&
  1070. this.Parent.GroupSettings.ExpandDirection == RadMenuNamespace.ExpandDirection.Right)
  1071. {
  1072. this.Parent.Focus();
  1073. }
  1074. else
  1075. {
  1076. if (this.Menu.OpenedItem)
  1077. {
  1078. this.Menu.OpenedItem.GetPreviousItem().Focus();
  1079. }
  1080. }
  1081. }
  1082. }
  1083. RadMenuItem.prototype.HandleUpArrow = function ()
  1084. {
  1085. if (this.Parent.Flow == RadMenuNamespace.ItemFlow.Vertical)
  1086. {
  1087. this.FocusPreviousItem();
  1088. }
  1089. else
  1090. {
  1091. this.FocusLastChild();
  1092. }
  1093. }
  1094. RadMenuItem.prototype.HandleDownArrow = function ()
  1095. {
  1096. if (this.Parent.Flow == RadMenuNamespace.ItemFlow.Vertical)
  1097. {
  1098. this.FocusNextItem();
  1099. }
  1100. else
  1101. {
  1102. this.FocusFirstChild();
  1103. }
  1104. }
  1105. RadMenuItem.prototype.GetNextItem = function ()
  1106. {
  1107. if (this.Index == this.Parent.Items.length - 1)
  1108. {
  1109. return this.Parent.Items[0];
  1110. }
  1111. return this.Parent.Items[this.Index + 1];
  1112. }
  1113. RadMenuItem.prototype.GetPreviousItem = function ()
  1114. {
  1115. if (this.Index == 0)
  1116. {
  1117. return this.Parent.Items[this.Parent.Items.length - 1];
  1118. }
  1119. return this.Parent.Items[this.Index - 1];
  1120. }
  1121. RadMenuItem.prototype.CanFocus = function ()
  1122. {
  1123. return (!this.IsSeparator) && this.Enabled;
  1124. }
  1125. RadMenuItem.prototype.FocusFirstChild = function ()
  1126. {
  1127. if (!this.Items.length)
  1128. {
  1129. return;
  1130. }
  1131. var item = this.Items[0];
  1132. while (!item.CanFocus())
  1133. {
  1134. item = item.GetNextItem();
  1135. if (item == this.Items[0])
  1136. {
  1137. return; // no items to focus
  1138. }
  1139. }
  1140. item.Focus();
  1141. }
  1142. RadMenuItem.prototype.FocusLastChild = function ()
  1143. {
  1144. if (!this.Items.length)
  1145. {
  1146. return;
  1147. }
  1148. var item = this.Items[this.Items.length - 1];
  1149. while (!item.CanFocus())
  1150. {
  1151. item = item.GetPreviousItem();
  1152. if (this.Items.length - 1)
  1153. {
  1154. return; // no items to focus
  1155. }
  1156. }
  1157. item.Focus();
  1158. }
  1159. RadMenuItem.prototype.FocusNextItem = function ()
  1160. {
  1161. var item = this.GetNextItem();
  1162. while (!item.CanFocus())
  1163. {
  1164. item = item.GetNextItem();
  1165. }
  1166. item.Focus();
  1167. }
  1168. RadMenuItem.prototype.FocusPreviousItem = function ()
  1169. {
  1170. var item = this.GetPreviousItem();
  1171. while (!item.CanFocus())
  1172. {
  1173. item = item.GetPreviousItem();
  1174. }
  1175. item.Focus();
  1176. }
  1177. RadMenuItem.prototype.RecordState = function (forceSerialize)
  1178. {
  1179. if (this.ClientSide && !forceSerialize)
  1180. {
  1181. return;
  1182. }
  1183. var serialized = RadControlsNamespace.JSON.stringify(this, this.InitialState, RadMenu.JSONIncludeDeep);
  1184. if (serialized == "{}")
  1185. {
  1186. this.Menu.ItemState[this.ID] = "";
  1187. }
  1188. else
  1189. {
  1190. this.Menu.ItemState[this.ID] = "\"" + this.ID + "\":" + serialized;
  1191. }
  1192. this.Menu.RecordState();
  1193. }
  1194. RadMenuItem.prototype.AddItem = function()
  1195. {
  1196. this.Menu.AddItem.apply(this, arguments);
  1197. this.Menu.FixItemWidth(this);
  1198. }
  1199. //BEGIN_ATLAS_NOTIFY
  1200. if (typeof(Sys) != "undefined")
  1201. {
  1202. if (Sys.Application != null && Sys.Application.notifyScriptLoaded != null)
  1203. {
  1204. Sys.Application.notifyScriptLoaded();
  1205. }
  1206. }
  1207. //END_ATLAS_NOTIFY