diff --git a/bin/SlideOut.js b/bin/SlideOut.js index 0ebe3aa02f9ddbfc28629ff02a40a41548a6298e..ec1d678f255da8290a8b6138e64bafc61bf44b56 100644 --- a/bin/SlideOut.js +++ b/bin/SlideOut.js @@ -37,7 +37,8 @@ define('package/quiqqer/menu/bin/SlideOut', [ 'menu-width' : 256, 'menu-button' : true, 'touch' : false, - 'buttonids' : false + 'buttonids' : false, + collapsemobilemenu : false }, Binds: [ @@ -103,6 +104,37 @@ define('package/quiqqer/menu/bin/SlideOut', [ }) }); + var Parent = this.getElm(), + ToggleButton = Parent.getElements(".quiqqer-menu-levels"); + + var runs = false; + + ToggleButton.addEvent("click", function (e) + { + e.preventDefault(); + + if (runs) { + return; + } + + runs = true; + + var LiLeft = this.getParent('li'); + var NavSubLeft = LiLeft.getElement("div.quiqqer-sub-nav-div"); + var Prom; + + if (!NavSubLeft.getSize().y.toInt()) { + Prom = self.openMenu(NavSubLeft); + } else { + Prom = self.closeMenu(NavSubLeft); + } + + Prom.then(function () + { + runs = false; + }); + }); + // fix for IE - z-index must have the value 0 if (navigator.appName == 'Microsoft Internet Explorer' || !!(navigator.userAgent.match(/Trident/) || @@ -479,6 +511,77 @@ define('package/quiqqer/menu/bin/SlideOut', [ } }).toElement(Target); }, 300); + }, + + /** + * open the next level of sub menu + * + * @param {HTMLLIElement} NavSubLeft + * + * @return Promise + */ + openMenu: function (NavSubLeft) + { + return new Promise(function (resolve) + { + NavSubLeft.setStyles({ + height : 0, + opacity : 0, + overflow: "hidden", + display : "block" + }); + + moofx(NavSubLeft).animate({ + height : NavSubLeft.getElement("ul").getSize().y.toInt(), + opacity: 1 + }, { + duration: 200, + callback: function () + { + NavSubLeft.setStyle('height', '100%'); + + var Prev = NavSubLeft.getPrevious('.quiqqer-navigation-entry'), + Icon = Prev.querySelector('.quiqqer-menu-levels'); + + if (Icon.hasClass('quiqqer-menu-levels')) { + Icon.addClass("quiqqer-menu-levels-rotate"); + } + + resolve(); + } + }); + }); + }, + + /** + * close the next level of sub menu + * + * @param {HTMLLIElement} NavSubLeft + * + * @return Promise + */ + closeMenu: function (NavSubLeft) + { + return new Promise(function (resolve) + { + NavSubLeft.setStyle("overflow", "hidden"); + NavSubLeft.setStyle("height", NavSubLeft.getSize().y); + + moofx(NavSubLeft).animate({ + height : 0, + opacity: 0 + }, { + duration: 200, + callback: function () + { + var Prev = NavSubLeft.getPrevious('.quiqqer-navigation-entry'), + Icon = Prev.querySelector('.quiqqer-menu-levels'); + + Icon.removeClass("quiqqer-menu-levels-rotate"); + resolve(); + }`` + }); + }); } }); diff --git a/locale.xml b/locale.xml index 7dbf2e858d3efdd2d5890fbf45d232305f662334..bc56260fdb37e6e3831fb5809e6bb03756c84371 100644 --- a/locale.xml +++ b/locale.xml @@ -26,6 +26,10 @@ <de><![CDATA[Dieser Wert ist in Millisekunden anzugeben. 250 bedeutet, dass das Untermenü erst dann erscheint, wenn man länger als 1/4 Sekunden mit der Maus wartet. Setzt man 0, wird das Untermenü sofort angezeigt.]]></de> <en><![CDATA[This value must be specified in milliseconds. 250 means that the submenu will only appear if you wait longer than 1/4 seconds with the mouse. If you set 0, the submenu will be displayed immediately.]]></en> </locale> + <locale name="menu.settings.collapseMobileSubmenu"> + <de><![CDATA[Collpase-Untermenü in der mobilen Version]]></de> + <en><![CDATA[Collpase submenu in mobile version]]></en> + </locale> <locale name="menu.settings.type"> <de><![CDATA[Menü Art]]></de> <en><![CDATA[Menu type]]></en> diff --git a/settings.xml b/settings.xml index ec006dde0c787279bef6c9e6c208bf4752701490..bd17bc558ea28c775c4121721ae16401f071e0a3 100644 --- a/settings.xml +++ b/settings.xml @@ -9,6 +9,9 @@ <type><![CDATA[number]]></type> <defaultvalue>250</defaultvalue> </conf> + <conf name="collapseMobileSubmenu"> + <type><![CDATA[bool]]></type> + </conf> <conf name="type"> <type><![CDATA[string]]></type> </conf> @@ -37,6 +40,12 @@ </description> </input> + <input conf="menu.settings.collapseMobileSubmenu" type="checkbox"> + <text> + <locale group="quiqqer/menu" var="menu.settings.collapseMobileSubmenu"/> + </text> + </input> + <select conf="menu.settings.type"> <text> <locale group="quiqqer/menu" var="menu.settings.type"/> diff --git a/src/QUI/Menu/MegaMenu.css b/src/QUI/Menu/MegaMenu.css index e9decb552ad08e9d23cd50941c81b5f9cb125199..8d613896b75205766a90b77e25f7694bd463c04e 100644 --- a/src/QUI/Menu/MegaMenu.css +++ b/src/QUI/Menu/MegaMenu.css @@ -52,4 +52,31 @@ font-size: 20px; line-height: 60px; padding: 0 10px; +} + +.quiqqer-menu-close { + display: none; +} + +.quiqqer-menu-levels { + transition: all 0.2s; + transition-timing-function: ease-in-out; +} + +.quiqqer-menu-levels-rotate { + transform: rotate(90deg); +} + +.quiqqer-navigation-entry .quiqqer-menu-active-level { + background: rgba(255, 255, 255, 0.10); + font-weight: 500; +} + +.page-navigation li { + margin-top: 0; + margin-bottom: 0; +} + +.page-navigation .page-navigation-level-1 a { + border: none; } \ No newline at end of file diff --git a/src/QUI/Menu/MegaMenu.php b/src/QUI/Menu/MegaMenu.php index c6dbfa83b16e421fafba4b761c7b76bca0f3973f..6baf6212ef1190f0800ec4bd5c8695f499166ae3 100644 --- a/src/QUI/Menu/MegaMenu.php +++ b/src/QUI/Menu/MegaMenu.php @@ -31,15 +31,16 @@ class MegaMenu extends AbstractMenu public function __construct($attributes = []) { $this->setAttributes([ - 'showStart' => false, - 'Start' => false, - 'startText' => '', // optional: displayed text - 'data-qui' => 'package/quiqqer/menu/bin/MegaMenu', - 'display' => 'Standard', - 'enableMobile' => true, - 'menuId' => false, - 'showFirstLevelIcons' => false, // current it works only for independent menu - 'showMenuDelay' => false + 'showStart' => false, + 'Start' => false, + 'startText' => '', // optional: displayed text + 'data-qui' => 'package/quiqqer/menu/bin/MegaMenu', + 'display' => 'Standard', + 'enableMobile' => true, + 'menuId' => false, + 'showFirstLevelIcons' => false, // current it works only for independent menu + 'showMenuDelay' => false, + 'collapseMobileSubmenu' => false ]); if ($this->getProject()->getConfig('menu.settings.type')) { @@ -49,7 +50,7 @@ public function __construct($attributes = []) parent::__construct($attributes); $this->addCSSClass('quiqqer-menu-megaMenu'); - $this->addCSSFile(dirname(__FILE__).'/MegaMenu.css'); + $this->addCSSFile(dirname(__FILE__) . '/MegaMenu.css'); if (!$this->getAttribute('enableMobile')) { return; @@ -76,6 +77,14 @@ public function __construct($attributes = []) $this->Mobile->setAttribute('data-qui-options-menu-button', 0); $this->Mobile->setAttribute('data-qui-options-touch', 0); $this->Mobile->setAttribute('data-qui-options-buttonids', 'mobileMenu'); + + $collapseMobileSubmenu = $this->getAttribute('collapseMobileSubmenu'); + + if ($this->getProject()->getConfig('menu.settings.collapseMobileSubmenu') !== '') { + $collapseMobileSubmenu = $this->getProject()->getConfig('menu.settings.collapseMobileSubmenu'); + } + + $this->Mobile->setAttribute('collapseMobileSubmenu', $collapseMobileSubmenu); } /** @@ -84,7 +93,7 @@ public function __construct($attributes = []) */ public function getBody() { - $cache = EventHandler::menuCacheName().'/megaMenu/'; + $cache = EventHandler::menuCacheName() . '/megaMenu/'; $attributes = $this->getAttributes(); $attributes = \array_filter($attributes, function ($entry) { @@ -92,7 +101,7 @@ public function getBody() }); $cache .= \md5( - $this->getSite()->getCachePath(). + $this->getSite()->getCachePath() . \serialize($attributes) ); @@ -164,7 +173,7 @@ public function getBody() ]); $result = []; - $result['html'] = $Engine->fetch(dirname(__FILE__).'/MegaMenu.Independent.html'); + $result['html'] = $Engine->fetch(dirname(__FILE__) . '/MegaMenu.Independent.html'); $result['subMenus'] = \array_unique($this->subMenus); } else { $Engine->assign([ @@ -187,7 +196,7 @@ public function getBody() } $result = []; - $result['html'] = $Engine->fetch(dirname(__FILE__).'/MegaMenu.html'); + $result['html'] = $Engine->fetch(dirname(__FILE__) . '/MegaMenu.html'); $result['subMenus'] = \array_unique($this->subMenus); } diff --git a/src/QUI/Menu/Menu.Children.html b/src/QUI/Menu/Menu.Children.html index a045a984d2e2fcfdb56a7ba5d2805d467680a264..48ed10d3db42265e96aee47b5455c7614e9700be 100644 --- a/src/QUI/Menu/Menu.Children.html +++ b/src/QUI/Menu/Menu.Children.html @@ -8,27 +8,57 @@ {/if} {if count($children)} -<ul class="page-navigation-level-{$level}"> - {foreach from=$children item=Child} - <li> - <a href="{url site=$Child}" class="left-menu-a"> - {if $ActiveSite->getId() == $Child->getId()} - <span class="fa fa-chevron-right"></span> - {else} - <span class="fa fa-angle-right"></span> - {/if} - - <span class="left-menu-text"> - {$Child->getAttribute('title')} - </span> - </a> - - {include file="`$FileMenu`" + +{assign hideSubmenu 'true'} + +{if $level > 1} +<div class="quiqqer-sub-nav-div {if $CollapseMobileSubmenu == 1}quiqqer-menu-close{/if}"> +{/if} + + <ul class="page-navigation-level-{$level}"> + {foreach from=$children item=Child} + <li> + <div class="quiqqer-navigation-entry"> + <a href="{url site=$Child}" class="left-menu-a {if $ActiveSite->getId() == $Child->getId()}quiqqer-menu-active-level{/if}"> + + {if count($Child->getNavigation())} + {* With children *} + + {if $ActiveSite->getId() == $Child->getId()} + <span class="fa fa-angle-double-right quiqqer-menu-levels + {if $CollapseMobileSubmenu == 0}quiqqer-menu-levels-rotate{/if}"></span> + {else} + <span class="fa fa-angle-double-right quiqqer-menu-levels + {if $CollapseMobileSubmenu == 0}quiqqer-menu-levels-rotate{/if}"></span> + {/if} + + {else} + {* Without children *} + + {if $ActiveSite->getId() == $Child->getId()} + <span class="fa fa-angle-right"></span> + {else} + <span class="fa fa-angle-right"></span> + {/if} + + {/if} + + <span class="left-menu-text"> + {$Child->getAttribute('title')} + </span> + </a> + </div> + + + {include file="`$FileMenu`" Site=$Child ActiveSite=$ActiveSite level=$level - } - </li> - {/foreach} -</ul> + } + </li> + {/foreach} + </ul> + {if $level > 1} + </div> + {/if} {/if} diff --git a/src/QUI/Menu/Menu.html b/src/QUI/Menu/Menu.html index 09f1a4034587c42bbb74a791c8a594b21641cd6a..90babb607a3a6c795414baade0929b48c17ddd3f 100644 --- a/src/QUI/Menu/Menu.html +++ b/src/QUI/Menu/Menu.html @@ -1,4 +1,4 @@ -<nav class="page-menu" data-qui="{$jsControl}" style="display: none;"> +<nav class="page-menu" data-qui="{$jsControl}" style="display: none;" data-qui-options-collapse-mobile-submenu={$collapseMobileSubmenu}> <div class="page-navigation {if !$showHomeLink}page-navigation__noHomeLink{/if}"> {if $showHomeLink} @@ -11,6 +11,7 @@ {include file="`$FileMenu`" Site=$Project->firstChild() ActiveSite=$Site + CollapseMobileSubmenu=$collapseMobileSubmenu } </div> </nav> diff --git a/src/QUI/Menu/SlideOut.php b/src/QUI/Menu/SlideOut.php index ed2dbe8b2c03f90a68af4e702793ead59f359587..5d9d5edf7770639e7b7cd435c798fd21b5cfeeca 100644 --- a/src/QUI/Menu/SlideOut.php +++ b/src/QUI/Menu/SlideOut.php @@ -39,6 +39,8 @@ public function getBody() { $Engine = QUI::getTemplateManager()->getEngine(); + $collapseMobileSubmenu = $this->getAttribute('collapseMobileSubmenu'); + $params = [ 'this' => $this, 'Project' => $this->getProject(), @@ -55,6 +57,7 @@ public function getBody() $params['showFirstLevelIcons'] = $this->getAttribute('showFirstLevelIcons'); } else { $template = dirname(__FILE__).'/Menu.html'; + $params['collapseMobileSubmenu'] = $collapseMobileSubmenu; $params['FileMenu'] = dirname(__FILE__).'/Menu.Children.html'; $params['Site'] = $this->getSite(); }