/* * Dropdown mobile friendly menu. * Is compatible with sircon ajax * @author Sircon Norge AS */ (function($){ sircon.vars.clickToggleMenuLoaded = true; var menuSelector = '[data-sirconClickToggleMenu]', cMenuOpen = 'toggle-open', cVisible = 'visible' //class given to levels above current level cCurrentVisible = 'current-visible'; //Class given to current visible level /** #### TRIGGERS FOR OPENING, TARGETING and CLOSING THE MENU #### **/ function closeAllOtherMenus($menuToKeep){ var $otherMenus = $(menuSelector).not($menuToKeep); clearAllVisibleClasses($otherMenus); $otherMenus.removeClass(cMenuOpen); } //Add a class to the menu mentioning how many levels deep we currently are function addDepthClass($menu){ var levelDepth = $menu.find('.visible').length; if($menu.hasClass('visible')){ levelDepth++; } for(var i=0; i<10; i++){ if(i==levelDepth){continue;} if(!$menu.hasClass('current-depth-'+i)){continue;} $menu.removeClass('current-depth-'+i); } $menu.addClass('current-depth-'+levelDepth); } //Clear "visible" and "current-visible" function clearAllVisibleClasses($menu){ $menu .removeClass(cCurrentVisible) .removeClass(cVisible) .find('.'+cVisible+', .'+cCurrentVisible) .removeClass(cCurrentVisible) .removeClass(cVisible); } //Event close menu $(document).on('closeMenu', menuSelector, function(event){ event.stopPropagation(); var $triggerer = $(this), $clickToggleMenu = $triggerer.closest(menuSelector); $clickToggleMenu.removeClass(cMenuOpen); clearAllVisibleClasses($clickToggleMenu); addDepthClass($clickToggleMenu); }); //Open the menu $(document).on('openMenu', menuSelector, function(event){ event.stopPropagation(); var $triggerer = $(this), $clickToggleMenu = $triggerer.closest(menuSelector); $clickToggleMenu.addClass(cMenuOpen); closeAllOtherMenus($clickToggleMenu); //Set current level menu item as visible var $currentMenuItem = $clickToggleMenu.find('.current-menu-item'); if($currentMenuItem.length > 0){ $currentMenuItem.parent().parent() .addClass(cVisible+' '+cCurrentVisible) .parentsUntil('nav, div', '.menu-item').addClass(cVisible); }else{ $clickToggleMenu.addClass(cVisible).addClass(cCurrentVisible); } addDepthClass($clickToggleMenu); }); //Target specific target level for opening $(document).on('openLevel', menuSelector+' .menu-item', function(event){ event.stopPropagation(); var $menuItem = $(this), $clickToggleMenu = $menuItem.closest(menuSelector); //Make sure menu opens up $clickToggleMenu.addClass(cMenuOpen); closeAllOtherMenus($clickToggleMenu); //Remove all currenly visible things clearAllVisibleClasses($clickToggleMenu); //Make target and parents work as visible $menuItem .addClass(cVisible+' '+cCurrentVisible) .parentsUntil('nav, div', '.menu-item').addClass(cVisible); $clickToggleMenu.addClass(cVisible); addDepthClass($clickToggleMenu); }); //Target specific target TOP level for opening $(document).on('openTopLevel', menuSelector, function(event){ event.stopPropagation(); var $clickToggleMenu = $(this); //Make sure menu opens up $clickToggleMenu.addClass(cMenuOpen); closeAllOtherMenus($clickToggleMenu); //Remove all currenly visible things clearAllVisibleClasses($clickToggleMenu); //Make target and parents work as visible $clickToggleMenu.addClass(cVisible+' '+cCurrentVisible); addDepthClass($clickToggleMenu); }); //Target specific target level for CLOSING $(document).on('closeLevel', menuSelector+' .menu-item', function(event){ event.stopPropagation(); var $menuItem = $(this), $clickToggleMenu = $menuItem.closest(menuSelector), $parentItem = $menuItem.parent().closest('.menu-item'); //Make sure menu opens up $clickToggleMenu.addClass(cMenuOpen); closeAllOtherMenus($clickToggleMenu); //hide target and make parents work as visible and current if($parentItem.length == 0){ //Now need to trigger top! $clickToggleMenu.trigger('openTopLevel'); }else{ //Has parent level to trigger $parentItem.closest('.menu-item').trigger('openLevel'); } addDepthClass($clickToggleMenu); }); /** #### CLICKS for triggering TRIGGERS #### **/ //Click outside menu should close the entire menu $(document).on('keyup', function(event){ if(event.which===27){ $(this).click(); return; } }); $(document).on('click', function(event){ //Check for click outside phonemenu var $this = $(event.target), $currentTargetMenu = $this.closest(menuSelector).last(), menuRelatedClick = $currentTargetMenu.length>0; if(!menuRelatedClick){ //Close menu and just return $(menuSelector).each(function(){ $(this).trigger('closeMenu'); }); return; } }); //Link clicks are the most interesting, and needs to work with ajax history jQuery(document).on('click keyup', '[data-sirconclick=toggle-submenu]', function(event){ if(event.which===13){ $(this).click(); return; } }); jQuery(document).on('click', '[data-sirconclick=toggle-submenu]', function(event){ event.stopPropagation(); var $this = $(this), $closestLi = $this.closest('li'), isCurrentlyVisible = $closestLi.hasClass(cCurrentVisible); if($this.attr('href') === '#'){ //Avoid adding the hashmark in the addressbar event.preventDefault(); } //Toggle current state if(isCurrentlyVisible){ //Is visible, so close it! $closestLi.trigger('closeLevel'); }else{ //Not currently visible, target submenu $closestLi.trigger('openLevel'); } }); $(document).on('click', '[data-sirconclick=submenu-back]', function(event){ event.stopPropagation(); var $this = $(this), $clickToggleMenu = $this.closest(menuSelector), $currentLevel = $clickToggleMenu.find('.'+cCurrentVisible); $currentLevel.trigger('closeLevel'); return; }); $(document).on('click', '[data-sirconclick=menu-top]', function(event){ event.stopPropagation(); var $this = $(this), $clickToggleMenu = $this.closest(menuSelector); $clickToggleMenu.trigger('openTopLevel'); return; }); $(document).on('click', '[data-sirconclick=trigger-phonemenu]', function(event){ event.stopPropagation(); var $this = $(this), $clickToggleMenu = $this.closest(menuSelector), menuOpen = $clickToggleMenu.hasClass(cMenuOpen); if(menuOpen){ $clickToggleMenu.trigger('closeMenu'); }else{ $clickToggleMenu.trigger('openMenu'); } return; }); })(jQuery);