lgduong
asked on
How to get CSS styled menu to maintain the open selected menu?
Hello experts,
I have a CSS accordion menu that I would like to have the selected menu item continued to be open after a link is clicked.
For example, to get to the "chicken.php" page, the menu is expanded to the Food Management menu item. If I want to click to the "beef.php" menu, it will maintain the expanded menu from the previous "chicken" page.
Here is my CSS menu:
<div id="menu">
<ul class="cm-accordion-menu">
<li class="main"><a href="/myhome.php">Home</a >
</li>
<li class="submenu">
<input type="checkbox" name ="group-aboutus" id="group-aboutus">
<label for="group-aboutus">About Us</label>
<ul>
<li><a href="aboutFDP.php">About FDP</a></li>
</ul>
</li>
<!-- METRICS -->
<li class="submenu">
<input type="checkbox" name ="group-metrics" id="group-metrics">
<label for="group-metrics">Metric s</label>
<ul>
<li><a href="metric_home.php">Met rics Homepage</a></li>
<!-- ACCESS MANAGEMENT -->
<li class="submenu">
<input type="checkbox" name ="subgroup-access" id="subgroup-access">
<label for="subgroup-access">Acce ss Management</label>
<ul>
<li><a href="access.php">Access Status</a></li>
<li><a hre="access_report.php">Ac cess Report</a></li>
</ul>
</li>
<!-- FOOD MANAGEMENT -->
<li class="submenu">
<input type="checkbox" name ="subgroup-asset" id="subgroup-asset">
<label for="subgroup-asset">Food Management</label>
<ul>
<li><a href="dairy.php">Dairy</a> </li>
<li><a href="beverages.php">Bever ages</a></ li>
<li><a href="produces.ph">Produce s</a></li>
<li class="submenu">
<input type="checkbox" name ="subgroup-meatFood" id="subgroup-meatFood">
<label for="subgroup-meatFood">Me at</label>
<ul>
<li><a href="chicken.php">Chicken </a></li>
<li><a href="pork.php">Pork</a></ li>
<li><a href="beef.php">Beef</a></ li>
<li><a href="seafood.php">Seafood </a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
styles.css
I have a CSS accordion menu that I would like to have the selected menu item continued to be open after a link is clicked.
For example, to get to the "chicken.php" page, the menu is expanded to the Food Management menu item. If I want to click to the "beef.php" menu, it will maintain the expanded menu from the previous "chicken" page.
Here is my CSS menu:
<div id="menu">
<ul class="cm-accordion-menu">
<li class="main"><a href="/myhome.php">Home</a
</li>
<li class="submenu">
<input type="checkbox" name ="group-aboutus" id="group-aboutus">
<label for="group-aboutus">About Us</label>
<ul>
<li><a href="aboutFDP.php">About FDP</a></li>
</ul>
</li>
<!-- METRICS -->
<li class="submenu">
<input type="checkbox" name ="group-metrics" id="group-metrics">
<label for="group-metrics">Metric
<ul>
<li><a href="metric_home.php">Met
<!-- ACCESS MANAGEMENT -->
<li class="submenu">
<input type="checkbox" name ="subgroup-access" id="subgroup-access">
<label for="subgroup-access">Acce
<ul>
<li><a href="access.php">Access Status</a></li>
<li><a hre="access_report.php">Ac
</ul>
</li>
<!-- FOOD MANAGEMENT -->
<li class="submenu">
<input type="checkbox" name ="subgroup-asset" id="subgroup-asset">
<label for="subgroup-asset">Food Management</label>
<ul>
<li><a href="dairy.php">Dairy</a>
<li><a href="beverages.php">Bever
<li><a href="produces.ph">Produce
<li class="submenu">
<input type="checkbox" name ="subgroup-meatFood" id="subgroup-meatFood">
<label for="subgroup-meatFood">Me
<ul>
<li><a href="chicken.php">Chicken
<li><a href="pork.php">Pork</a></
<li><a href="beef.php">Beef</a></
<li><a href="seafood.php">Seafood
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
styles.css
If I understand properly, you would like to click on a dropdown link and open that link on this current page and keep the dropdown open.
If this is the case, I would recommend you to think about it twice because it won't be a good user experience for your clients. Since, they already decided to read/interact with a specific page and now there is something in their way that is preventing them to do so.
However, you can add "target="_blank" to you <a> tags in order to keep that page open with the selected submenu open. Take in consideration that this might also be annoying since a new window will be open every time a dropdown link is clicked or use @Julian Hansen solution.
If this is the case, I would recommend you to think about it twice because it won't be a good user experience for your clients. Since, they already decided to read/interact with a specific page and now there is something in their way that is preventing them to do so.
However, you can add "target="_blank" to you <a> tags in order to keep that page open with the selected submenu open. Take in consideration that this might also be annoying since a new window will be open every time a dropdown link is clicked or use @Julian Hansen solution.
ASKER
Julian,
I'm sorry that I forgot to mention that it is a left menu navigation. It is a common include file.
What am I doing wrong?
Due to the fact that I have other javascript files, I have to add a noconflict method to avoid conflicts.
Here is the code:
<script type="text/javascript">
var $jquery = jQuery.noConflict();
$jquery(document).ready(fu nction ()
{
var page = window.location.href.split ('/').slic e(-1);
var link = $jquery('a[href="' + page + '"]').closest('.submenu') || [];
alert("link is :: "+link);
while (link.length > 0)
{
link.children('input').pro p('checked ',true);
link = link.parent().closest('.su bmenu') || [];
}
});
The alert message is "link is :: [objet Object]". Why can't it get the closest submenu?
I'm not proficient with jquery or javascript.
Please help.
I'm sorry that I forgot to mention that it is a left menu navigation. It is a common include file.
What am I doing wrong?
Due to the fact that I have other javascript files, I have to add a noconflict method to avoid conflicts.
Here is the code:
<script type="text/javascript">
var $jquery = jQuery.noConflict();
$jquery(document).ready(fu
{
var page = window.location.href.split
var link = $jquery('a[href="' + page + '"]').closest('.submenu') || [];
alert("link is :: "+link);
while (link.length > 0)
{
link.children('input').pro
link = link.parent().closest('.su
}
});
The alert message is "link is :: [objet Object]". Why can't it get the closest submenu?
I'm not proficient with jquery or javascript.
Please help.
Instead of alert do this
console.log(link)
And then check the console (F7)
Is the menu the only place those links occur? It might be prudent to put a class on the menu and then prefix the selector with the class ex.
Let's see what the console.log(link) does.
console.log(link)
And then check the console (F7)
Is the menu the only place those links occur? It might be prudent to put a class on the menu and then prefix the selector with the class ex.
var link = $jquery('.main-menu a[href="' + page + '"]').closest('.submenu') || [];
Let's see what the console.log(link) does.
ASKER
Julian,
The console displays "Object { length: 0, prevObject: Object }
When I manually add the "checked" to the first <input> it will expand that main menu but not any of the cascading submenu.
If I were to add "checked" to the 2nd or 3rd submenu, nothing is expanded, not even the "main" menu for that section.
for example, if checked is add to the 2nd submenu under Reports
the "main" menu section (Reports) is not expanded.
The console displays "Object { length: 0, prevObject: Object }
When I manually add the "checked" to the first <input> it will expand that main menu but not any of the cascading submenu.
If I were to add "checked" to the 2nd or 3rd submenu, nothing is expanded, not even the "main" menu for that section.
for example, if checked is add to the 2nd submenu under Reports
<input type="checkbox" name ="subgroup-itReport" id="subgroup-itReport" checked>
the "main" menu section (Reports) is not expanded.
<div id="menu">
<ul class="cm-accordion-menu">
<li class="submenu">
[i][b]** if "checked" is true here, it will expand **[/b][/i]
<input type="checkbox" name ="group-processes" id="group-processes" checked>
<label for="group-processes">Processes</label>
<ul>
<li><a href="processHome.php">Processes Home</a></li>
<li><a href="process1.php">Process1</a></li>
</ul>
</li>
<li class="submenu">
[i][b]** if "checked" is true here, it will expand **[/b][/i]
<input type="checkbox" name ="group-reports" id="group-reports" >
<label for="group-reports">Reports</label>
<ul>
<li><a href="#0">ISCM Reports</a></li>
<li class="submenu">
[i][b]** if "checked" is true here, nothing happen**[/b][/i]
<input type="checkbox" name ="subgroup-itReport" id="subgroup-itReport" >
<label for="subgroup-itReport">Reporting</label>
<ul>
<li><a href="weekly.php">Weekly</a></li>
<li class="submenu">
[i][b]** if "checked" is true here, nothing happen**[/b][/i]
<input type="checkbox" name ="subgroup-reportMonthly" id="subgroup-reportMonthly">
<label for="subgroup-reportMonthly">Monthly</label>
<ul>
<li><a href="report1.php">Report1</a></li>
<li><a href="report2.php">Report2</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
This sample shows the case where you can manually add checked to the bottom
I applied the jQuery above to this menu as well and manually coded the page variable to test different scripts in the menu - all worked fine.
<div id="menu">
<ul class="cm-accordion-menu">
<li class="submenu">
<input type="checkbox" name ="group-processes" id="group-processes">
<label for="group-processes">Processes</label>
<ul>
<li><a href="processHome.php">Processes Home</a></li>
<li><a href="process1.php">Process1</a></li>
</ul>
</li>
<li class="submenu">
<input type="checkbox" name ="group-reports" id="group-reports" checked >
<label for="group-reports">Reports</label>
<ul>
<li><a href="#0">ISCM Reports</a></li>
<li class="submenu">
<input type="checkbox" name ="subgroup-itReport" id="subgroup-itReport" checked>
<label for="subgroup-itReport">Reporting</label>
<ul>
<li><a href="weekly.php">Weekly</a></li>
<li class="submenu">
<input type="checkbox" name ="subgroup-reportMonthly" id="subgroup-reportMonthly" checked>
<label for="subgroup-reportMonthly">Monthly</label>
<ul>
<li><a href="report1.php">Report1</a></li>
<li><a href="report2.php">Report2</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
Working sample hereI applied the jQuery above to this menu as well and manually coded the page variable to test different scripts in the menu - all worked fine.
ASKER
Julian,
You are absolutely right. By adding the "checked" to all 3 level of the input field, it will keep those open.
Yet I am still having problems with the jquery method to the process to add the "checked" selector.
The alert message is "link is :: [object Object]".
What is wrong with my jquery that it is not giving me the "link"?
Please be patience with me. jQuery/javascript is really not my strong point.
You are absolutely right. By adding the "checked" to all 3 level of the input field, it will keep those open.
Yet I am still having problems with the jquery method to the process to add the "checked" selector.
<script type="text/javascript">
var $jquery = jQuery.noConflict();
$jquery(function()
{
var page = window.location.href.split('/').slice(-1);
var link = $jquery('a[href="' + page + '"]').closest('.submenu') || false;
alert("link is :: "+link);
while (link.length > 0)
{
link.children('input').prop('checked',true);
link = link.parent().closest('.submenu') || false;
}
});
</script>
The alert message is "link is :: [object Object]".
What is wrong with my jquery that it is not giving me the "link"?
Please be patience with me. jQuery/javascript is really not my strong point.
The alert message is "link is :: [object Object]".There is nothing wrong with this message - it is what you should see in an alert. Which is why I suggested you use console.log(link) instead - the console shows a lot more information.
Add this at line 7
console.log(page)
We need to check that the page that is being retrieved matches a link on the page. Also change window.location.href to window.location.pathname
<script>
$(function() {
var page = window.location.pathname.split('/').slice(-1);
console.log(page);
var page = 'access_report.php';
var link = $('a[href="' + page + '"]').closest('.submenu') || false;
console.log(link);
while (link.length > 0) {
link.children('input').prop('checked',true);
link = link.parent().closest('.submenu') || false;
}
});
</script>
ASKER
Hi Julian,
I've converted my webpage to html extension and it does work. However, if the url link is an absolute path or a layer deeper, it does not work in expanding the menu. What am I doing work or missing?
I've converted my webpage to html extension and it does work. However, if the url link is an absolute path or a layer deeper, it does not work in expanding the menu. What am I doing work or missing?
<div id="menu">
<ul class="cm-accordion-menu">
<li class="submenu">
<input type="checkbox" name ="group-processes" id="group-processes">
<label for="group-processes">Processes</label>
<ul>
<li><a href="/home/processHome.php">Processes Home</a></li>
<li><a href="/home/proc/process1.php">Process1</a></li>
</ul>
</li>
<li class="submenu">
<input type="checkbox" name ="group-reports" id="group-reports" checked >
<label for="group-reports">Reports</label>
<ul>
<li><a href="#0">Reports</a></li>
<li class="submenu">
<input type="checkbox" name ="subgroup-itReport" id="subgroup-itReport" checked>
<label for="subgroup-itReport">Reporting</label>
<ul>
<li><a href="weekly.php">Weekly</a></li>
<li class="submenu">
<input type="checkbox" name ="subgroup-reportMonthly" id="subgroup-reportMonthly" checked>
<label for="subgroup-reportMonthly">Monthly</label>
<ul>
<li><a href="level1/report1.php">Report1</a></li>
<li><a href="level1/report/report2.php">Report2</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
ASKER
Julian or anyone,
Can you please help me with the new problem of the link being several layers (/level1/level2/page.html) instead of only one layer (page.html)?
Thanks.
Can you please help me with the new problem of the link being several layers (/level1/level2/page.html)
Thanks.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thank you for your help.
You are welcome.
What you need to do is when you render your menu you need to check the page you are going to and make sure you set the checkboxes in the menu hierarchy to checked for each node in the tree that leads to the destination page.
You can do it with JavaScript as well -
Requires jQuery to be loaded before this.
Open in new window
Edit
Changed false to [] as the check is on link.length - requires an object with a length property so using empty array.