Skip to content

Commit a1dd3dc

Browse files
authored
Fix menu highlighting to show correct active page (#7724)
## What Changed <!-- Short summary - what and why (not how) --> - Improve isActive() to properly match URLs with query parameters - Menu items with query params only match when params are present - Menu items without query params only match when URL has no params - Make openMenu() recursive for nested submenu support - Change submenu container from div to li for proper AdminLTE styling - Add active class to nav-link for proper visual highlighting ## Type <!-- Check one --> - [ ] ✨ Feature - [x] 🐛 Bug fix - [ ] ♻️ Refactor - [ ] 🏗️ Build/Infrastructure - [ ] 🔒 Security ## Screenshots <!-- Only for UI changes - drag & drop images here --> <img width="428" height="733" alt="image" src="https://github.com/user-attachments/assets/86d83566-a7f9-4a23-9a68-e686f5af5670" /> ## Security Check <!-- Only check if applicable --> - [ ] Introduces new input validation - [ ] Modifies authentication/authorization - [ ] Affects data privacy/GDPR ### Code Quality - [ ] Database: Propel ORM only, no raw SQL - [ ] No deprecated attributes (align, valign, nowrap, border, cellpadding, cellspacing, bgcolor) - [ ] Bootstrap CSS classes used - [ ] All CSS bundled via webpack ## Pre-Merge - [x] Tested locally - [ ] No new warnings - [ ] Build passes - [ ] Backward compatible (or migration documented)
2 parents aa955df + d72ade0 commit a1dd3dc

File tree

2 files changed

+45
-5
lines changed

2 files changed

+45
-5
lines changed

src/ChurchCRM/Config/Menu/MenuItem.php

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,14 @@ public function isVisible(): bool
118118
public function openMenu(): bool
119119
{
120120
foreach ($this->subItems as $item) {
121+
// Check if this child is active
121122
if ($item->isActive()) {
122123
return true;
123124
}
125+
// Recursively check if any nested submenu has an active item
126+
if ($item->isMenu() && $item->openMenu()) {
127+
return true;
128+
}
124129
}
125130

126131
return false;
@@ -132,6 +137,41 @@ public function isActive(): bool
132137
return false;
133138
}
134139

135-
return $_SERVER['REQUEST_URI'] == $this->getURI();
140+
$menuUri = $this->getURI();
141+
$currentUri = $_SERVER['REQUEST_URI'];
142+
143+
// Parse both URIs
144+
$currentPath = parse_url($currentUri, PHP_URL_PATH);
145+
$menuPath = parse_url($menuUri, PHP_URL_PATH);
146+
$menuQuery = parse_url($menuUri, PHP_URL_QUERY);
147+
$currentQuery = parse_url($currentUri, PHP_URL_QUERY);
148+
149+
// Paths must match first
150+
if ($currentPath !== $menuPath) {
151+
return false;
152+
}
153+
154+
// If menu item has query params, check they all match
155+
if (!empty($menuQuery)) {
156+
if (empty($currentQuery)) {
157+
return false;
158+
}
159+
160+
parse_str($menuQuery, $menuParams);
161+
parse_str($currentQuery, $currentParams);
162+
163+
// Check if all menu params exist in current params with same values
164+
foreach ($menuParams as $key => $value) {
165+
if (!isset($currentParams[$key]) || $currentParams[$key] !== $value) {
166+
return false;
167+
}
168+
}
169+
170+
return true;
171+
}
172+
173+
// Menu item has NO query params - only match if current URL also has no query params
174+
// This prevents "/v2/family" from matching "/v2/family?mode=inactive"
175+
return empty($currentQuery);
136176
}
137177
}

src/ChurchCRM/view/MenuRenderer.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ private static function renderMenuItem(MenuItem $menuItem): void
2525
{
2626
?>
2727
<li class="nav-item<?= $menuItem->isActive() ? " active" : ""?>">
28-
<a href="<?= htmlspecialchars($menuItem->getURI(), ENT_QUOTES, 'UTF-8') ?>" <?= $menuItem->isExternal() ? "target='_blank'" : "" ?> class="nav-link">
28+
<a href="<?= htmlspecialchars($menuItem->getURI(), ENT_QUOTES, 'UTF-8') ?>" <?= $menuItem->isExternal() ? "target='_blank'" : "" ?> class="nav-link<?= $menuItem->isActive() ? " active" : ""?>">
2929
<i class='nav-icon fa <?= $menuItem->getIcon() ?>'></i>
3030
<p>
3131
<span><?= htmlspecialchars($menuItem->getName()) ?></span>
@@ -41,8 +41,8 @@ private static function renderMenuItem(MenuItem $menuItem): void
4141
private static function renderSubMenuItem(MenuItem $menuItem): void
4242
{
4343
?>
44-
<div class="nav-item<?= $menuItem->openMenu() ? " menu-open active" : "" ?>">
45-
<a href="#" class="nav-link">
44+
<li class="nav-item<?= $menuItem->openMenu() ? " menu-open" : "" ?>">
45+
<a href="#" class="nav-link<?= $menuItem->openMenu() ? " active" : "" ?>">
4646
<i class="nav-icon fa <?= $menuItem->getIcon() ?>"></i>
4747
<p>
4848
<span><?= htmlspecialchars($menuItem->getName()) ?></span>
@@ -63,7 +63,7 @@ private static function renderSubMenuItem(MenuItem $menuItem): void
6363
}
6464
} ?>
6565
</ul>
66-
</div>
66+
</li>
6767
<?php
6868
}
6969

0 commit comments

Comments
 (0)