Link to home
Start Free TrialLog in
Avatar of lgduong
lgduongFlag for United States of America

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">Metrics</label>
                                    <ul>
                                          <li><a href="metric_home.php">Metrics Homepage</a></li>

                                          <!-- ACCESS MANAGEMENT -->
                                          <li class="submenu">
                                                <input type="checkbox" name ="subgroup-access" id="subgroup-access">
                                                <label for="subgroup-access">Access Management</label>

                                                <ul>
                                                      <li><a href="access.php">Access Status</a></li>
                                                      <li><a hre="access_report.php">Access 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">Beverages</a></li>
                                                      <li><a href="produces.ph">Produces</a></li>
                                                      <li class="submenu">
                                                            <input type="checkbox" name ="subgroup-meatFood" id="subgroup-meatFood">
                                                                  <label for="subgroup-meatFood">Meat</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
Avatar of Julian Hansen
Julian Hansen
Flag of South Africa image

How is your menu rendered when you click on a link? Is it a common include file?

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.
<script>
$(function() {
  var page = window.location.href.split('/').slice(-1);
  var link = $('a[href="' + page + '"]').closest('.submenu') || [];
  while (link.length > 0) {
    link.children('input').prop('checked',true);
    link = link.parent().closest('.submenu') || [];
  }
});
</script>

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.
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.
Avatar of lgduong

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(function ()
                  {                        
                        var page = window.location.href.split('/').slice(-1);
                        
                        var link = $jquery('a[href="' + page + '"]').closest('.submenu') || [];
                        
                        alert("link is :: "+link);
                        
                        while (link.length > 0)
                        {
                              link.children('input').prop('checked',true);
                              link = link.parent().closest('.submenu') || [];
                        }
                  });

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.

var link = $jquery('.main-menu a[href="' + page + '"]').closest('.submenu') || [];

Open in new window


Let's see what the console.log(link) does.
Avatar of lgduong

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

<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>

Open in new window

This sample shows the case where you can manually add checked to the bottom

 <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>

Open in new window

Working sample here

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.
Avatar of lgduong

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.

<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>

Open in new window


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>

Open in new window

Avatar of lgduong

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?

 <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>

Open in new window

Avatar of lgduong

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.
ASKER CERTIFIED SOLUTION
Avatar of Julian Hansen
Julian Hansen
Flag of South Africa image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of lgduong

ASKER

Thank you for your help.
You are welcome.