From 6e11e497092a54b6f3ba614bb9f8282788f98c05 Mon Sep 17 00:00:00 2001 From: Alex-Code Date: Wed, 5 Mar 2014 16:50:02 +0000 Subject: [PATCH 1/3] sub menus didn't get checked for being active. Based off the method in ```Menu.php``` I've updated ```Nav``` so it will check if sub menus are active or not. --- Nav.php | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/Nav.php b/Nav.php index 9d4afc0..8e2075c 100644 --- a/Nav.php +++ b/Nav.php @@ -75,6 +75,10 @@ class Nav extends Widget */ public $activateItems = true; /** + * @var boolean whether to activate parent menu items when one of the corresponding child menu items is active. + */ + public $activateParents = false; + /** * @var string the route used to determine if a menu item is active or not. * If not set, it will use the route of the current request. * @see params @@ -110,11 +114,37 @@ class Nav extends Widget */ public function run() { + $this->activateItems($this->items, $hasActiveChild); echo $this->renderItems(); BootstrapAsset::register($this->getView()); } /** + * Check for active items adding the active class if found. + * @param array $items the items to check + * @param boolean $active does an item have an active child + */ + protected function activateItems(&$items, &$active) + { + foreach ($items as &$item) { + $hasActiveChild = false; + if (isset($item['items']) && is_array($item['items'])) { + $this->activateItems($item['items'], $hasActiveChild); + } + if (!isset($item['active'])) { + if ($this->activateParents && $hasActiveChild || $this->activateItems && $this->isItemActive($item)) { + $active = $item['active'] = true; + } + } elseif ($item['active']) { + $active = true; + } + if (ArrayHelper::remove($item, 'active', false)) { + Html::addCssClass($item['options'], 'active'); + } + } + } + + /** * Renders widget items. */ public function renderItems() @@ -151,16 +181,6 @@ class Nav extends Widget $url = ArrayHelper::getValue($item, 'url', '#'); $linkOptions = ArrayHelper::getValue($item, 'linkOptions', []); - if (isset($item['active'])) { - $active = ArrayHelper::remove($item, 'active', false); - } else { - $active = $this->isItemActive($item); - } - - if ($active) { - Html::addCssClass($options, 'active'); - } - if ($items !== null) { $linkOptions['data-toggle'] = 'dropdown'; Html::addCssClass($options, 'dropdown'); From 90c574655f4a5995f2ae3b9fe0d29441bbc33658 Mon Sep 17 00:00:00 2001 From: Alex-Code Date: Tue, 11 Mar 2014 13:10:09 +0000 Subject: [PATCH 2/3] Improved check for active child items Updated to avoid full tree traversal. Also noticed ```activateItems``` didn't do anything so that's been fixed. --- Nav.php | 61 +++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 33 insertions(+), 28 deletions(-) diff --git a/Nav.php b/Nav.php index 8e2075c..97bade5 100644 --- a/Nav.php +++ b/Nav.php @@ -114,37 +114,11 @@ class Nav extends Widget */ public function run() { - $this->activateItems($this->items, $hasActiveChild); echo $this->renderItems(); BootstrapAsset::register($this->getView()); } /** - * Check for active items adding the active class if found. - * @param array $items the items to check - * @param boolean $active does an item have an active child - */ - protected function activateItems(&$items, &$active) - { - foreach ($items as &$item) { - $hasActiveChild = false; - if (isset($item['items']) && is_array($item['items'])) { - $this->activateItems($item['items'], $hasActiveChild); - } - if (!isset($item['active'])) { - if ($this->activateParents && $hasActiveChild || $this->activateItems && $this->isItemActive($item)) { - $active = $item['active'] = true; - } - } elseif ($item['active']) { - $active = true; - } - if (ArrayHelper::remove($item, 'active', false)) { - Html::addCssClass($item['options'], 'active'); - } - } - } - - /** * Renders widget items. */ public function renderItems() @@ -181,12 +155,21 @@ class Nav extends Widget $url = ArrayHelper::getValue($item, 'url', '#'); $linkOptions = ArrayHelper::getValue($item, 'linkOptions', []); + if (isset($item['active'])) { + $active = ArrayHelper::remove($item, 'active', false); + } else { + $active = $this->isItemActive($item); + } + if ($items !== null) { $linkOptions['data-toggle'] = 'dropdown'; Html::addCssClass($options, 'dropdown'); Html::addCssClass($linkOptions, 'dropdown-toggle'); $label .= ' ' . Html::tag('b', '', ['class' => 'caret']); if (is_array($items)) { + if ($this->activateItems) { + $items = $this->isChildActive($items, $active); + } $items = Dropdown::widget([ 'items' => $items, 'encodeLabels' => $this->encodeLabels, @@ -195,10 +178,32 @@ class Nav extends Widget ]); } } - + + if ($this->activateItems && $active) { + Html::addCssClass($options, 'active'); + } + return Html::tag('li', Html::a($label, $url, $linkOptions) . $items, $options); } - + + /** + * Check to see if a child item is active optionally activating the parent. + * @param array $items @see items + * @param boolean $active should the parent be active too + * @return array @see items + */ + protected function isChildActive($items, &$active) + { + foreach ($items as $i => $child) { + if (ArrayHelper::remove($items[$i], 'active', false) || $this->isItemActive($child)) { + Html::addCssClass($items[$i]['options'], 'active'); + if ($this->activateParents) { + $active = true; + } + } + } + return $items; + } /** * Checks whether a menu item is active. From aa3854491235c0841bdf78a8885f97b86b131397 Mon Sep 17 00:00:00 2001 From: Alex-Code Date: Tue, 11 Mar 2014 13:16:12 +0000 Subject: [PATCH 3/3] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5fced15..eaee9ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ Yii Framework 2 bootstrap extension Change Log - Enh #1601: Added support for tagName and encodeLabel parameters in ButtonDropdown (omnilight) - Enh #1881: Improved `yii\bootstrap\NavBar` with `containerOptions`, `innerContainerOptions` and `renderInnerContainer` (creocoder) - Enh #2425: Tabs widget now selects first tab if no active tab is specified (samdark) +- Enh #2634: Submenus will now be checked for being active (Alex-Code) - Chg #1459: Update Collapse to use bootstrap 3 classes (tonydspaniard) - Chg #1820: Update Progress to use bootstrap 3 markup (samdark)