Question

I have a pretty complex nested accordion tree navigation "working" @ http://www.medlargroup.com the test site for a client.

It appears to work correctly only it is not collapsed by default and so is incredibly long. I attempted to put the various divs and classes around it as bootstrap intended but I got a very complex mess and also inappropriate styling I would then have to over-write.

If anyone could advise me of a JavaScript solution to make the boxes auto-collapse when not part of the active tree it would be much appreciated.

The php generated nav is as follows:

N.B. the variable $id is set at 0 from outside and parsed in when the snippet is called. It is a recursive function so it makes the standard div wraps even more complicated and an alternative js solution more attractive.

<?php if(!isset($subpages)) $subpages = $site->pages() ?> 

<?php $id+=1 ?>
<ul id="accordiongroup_<?php echo $id ?>" class"collapse in">

<?php
foreach($subpages->visible() AS $p): ?>
<li class="depth-<?php echo $p->depth() ?>">
<a href="#accordiongroup_<?php echo $id+1 ?>" data-toggle="collapse" data-parent="<?php echo $id ?>" >
<?php if($p->hasChildren())
    { echo $p->title() ?></a>
<?php snippet('accordionmenu', array('subpages' => $p->children(), 'id' => $id)) ?> 
<?php $id+=1;}


 else { ?>
    <a class=" <?php echo ($p->isActive()) ? 'active' : '' ?>" href="<?php echo $p->url() ?>"><?php echo $p->title() ?></a>

<?php }
?>    
  </li>
  <?php endforeach;?>
</ul>
Was it helpful?

Solution 2

Probably your easiest solution is to use a JQuery plugin like this one https://github.com/tommcfarlin/Collapsible-Menus. It's easy to use, and doesn't require much in the way of additional markup.

However, you're trying to do this with Bootstrap, so I'll try to help you find a solution using that. The first thing to notice is some errors in your code;

<ul id="accordiongroup_2" class"collapse in">

should be

<ul id="accordiongroup_2" class="collapse in">

That may be preventing some of the crucial styles from working. Essentially, to collapse a sub-menu, you just need to give the 'ul' a class of "collapsed". It's then a matter of using logic to work out which is your active menu item, and not adding the collapsed class to that.

Your problem will arise trying to work out the parent 'li' so you don't collapse them either. One way to do this on the server side might be to create a small function that tests if an 'li' element has a child 'ul' with a child 'li' that is active. If so, then set that 'li' to be active too. You'll need to get the data as a nested array first, and you'll need to run it though the number of times as your maximum nest depth.

OTHER TIPS

there are quite a lot of errors in the code you're generating, so I've made some here so you can see what's going on. I've stripped out everything that's not required for the accordion menu to work.

<div class="accordion">
<ul id="accordion1" class="collapse in">

<li>
    <a href="#accordion2" data-toggle="collapse" >About</a>

    <ul id="accordion2" class="collapse">
        <li>
            <a data-toggle="collapse" href="http://www.medlargroup.com/about/bio">Biography</a>
        </li>
        <li>
            <a data-toggle="collapse" href="http://www.medlargroup.com/about/cv">CV</a>
        </li>
        <li>
            <a data-toggle="collapse" href="http://www.medlargroup.com/about/press">Press</a>
        </li>
    </ul>

</li>

<li>
    <a href="#accordion3" data-toggle="collapse" >Work</a>

    <ul id="accordion3" class="collapse">
        <li>
            <a href="#accordion4" data-toggle="collapse">Cornwall</a>

            <ul id="accordion4" class="collapse">
                <li>
                    <a data-toggle="collapse" href="http://www.medlargroup.com/work/cornwall/cornwall_early">Cornwall 58-65</a>
                </li>
                <li>
                    <a data-toggle="collapse" href="http://www.medlargroup.com/work/cornwall/cornwall">Cornwall 66-69</a>
                </li>
                <li>
                    <a data-toggle="collapse" href="http://www.medlargroup.com/work/cornwall/cornwall_wave">Cornwall 69, Wave</a>
                </li>
            </ul>

        </li>

        <li>
            <a href="#accordion5" data-toggle="collapse">Whale Moor &amp; Lake District</a>

            <ul id="accordion5" class="collapse">
                <li>
                    <a data-toggle="collapse" href="http://www.medlargroup.com/work/whale_moor/one">Lakeland Hills 72-74</a>
                </li>
                <li>
                    <a data-toggle="collapse" href="http://www.medlargroup.com/work/whale_moor/two">Lakeland Hills 74-76</a>
                </li>
                <li>
                    <a data-toggle="collapse" href="http://www.medlargroup.com/work/whale_moor/three">Lakeland Hills 80</a>
                </li>
                <li>
                    <a data-toggle="collapse" href="http://www.medlargroup.com/work/whale_moor/four">High Places 82-83</a>
                </li>
                <li class="active">
                    <a data-toggle="collapse" href="http://www.medlargroup.com/work/whale_moor/lakes">Lakes of Cumberland 82</a>
                </li>
            </ul>
        </li>

        <li>
            <a href="#accordion6" data-toggle="collapse">Galloway &amp; Scottish Coast</a>

            <ul id="accordion6" class="collapse">
                <li class="depth-3">
                    <a  data-toggle="collapse" href="http://www.medlargroup.com/work/galloway/first">Galloway Coast 72-74</a>
                </li>
                <li class="depth-3">
                    <a  data-toggle="collapse" href="http://www.medlargroup.com/work/galloway/drumbreddan">Drumbreddan 76</a>
                </li>
                <li class="depth-3">
                    <a  data-toggle="collapse" href="http://www.medlargroup.com/work/galloway/pebble">Pebble Series 77-79</a>
                </li>
                <li class="depth-3">
                    <a  data-toggle="collapse" href="http://www.medlargroup.com/work/galloway/fidden">Fidden & The Isle of Mull</a>
                </li>
                <li class="depth-3">
                    <a  data-toggle="collapse" href="http://www.medlargroup.com/work/galloway/later">Later</a>
                </li>
            </ul>

        </li>

        <li>
            <a data-toggle="collapse" href="http://www.medlargroup.com/work/durdle">South Coast</a>
        </li>

        <li>
            <a href="#accordion7" data-toggle="collapse">Figures</a>

            <ul id="accordion7" class="collapse">
                <li>
                    <a data-toggle="collapse" href="http://www.medlargroup.com/work/figures/one">Figures 81</a>
                </li>
                <li">
                    <a data-toggle="collapse" href="http://www.medlargroup.com/work/figures/two">Figures 82-84</a>
                </li>
                <li class="depth-3">
                    <a  data-toggle="collapse" href="http://www.medlargroup.com/work/figures/three">Figures on the Beach 83</a>
               </li>
            </ul>

        </li>

        <li>
            <a  data-toggle="collapse" href="http://www.medlargroup.com/work/london">London</a>
        </li>

        <li>
            <a data-toggle="collapse" href="http://www.medlargroup.com/work/mersey">Merseyside</a>
        </li>

        <li>
            <a data-toggle="collapse" href="http://www.medlargroup.com/work/northumberland">Northumberland</a>
        </li>

        <li>
            <a href="#accordion8" data-toggle="collapse" >Wales &amp; the Llyn Peninsula</a>

            <ul id="accordion8" class="collapse">
                <li>
                    <a data-toggle="collapse" href="http://www.medlargroup.com/work/wales/one">Llanina 82</a>
               </li>
                <li>
                    <a data-toggle="collapse" href="http://www.medlargroup.com/work/wales/two">llyn</a>
                </li>
            </ul>

        </li>
    </ul>
  </li>

  <li>
    <a data-toggle="collapse" href="http://www.medlargroup.com/contact">Contact</a>
  </li>
</ul>
</div>

That will tidy up the code so that the various css selectors and the javascript can work ok. In addition, to keep the active menu item open, you will need to add a class 'active' to the active 'li' element, then run this code;

<script type="text/javascript">
    $('.active').parentsUntil('div.accordion').addClass('in');
</script>

That will add a class of 'in' to every parent of the active element, up to the top level. This will make them open for you.

The following snippet has a correction which makes the lists auto collapse, bar the first one.

With Joe's advice I also solved the question of how to hold the open branch open .

 <?php if(!isset($subpages)) $subpages = $site->pages() ?> 

<?php $id+=1;
foreach($site->breadcrumb() AS $crumb): 
   $breadcrumb[] = $crumb->url();
    endforeach ?>


<ul id="accordiongroup_<?php echo $id ?>" class="collapse <?php if ($id==1) {echo 'in';}?> 

<?php 
foreach ($subpages->visible() AS $sp):
if(in_array($sp->url(), $breadcrumb)) {echo 'in';}
endforeach; ?>
">


<?php

foreach($subpages->visible() AS $p): ?>
<li class="depth-<?php echo $p->depth() ?>">

<?php if($p->hasChildren()){?>
    <a href="#accordiongroup_<?php echo $id+1 ?>" data-toggle="collapse" data-parent="<?php echo $id ?>"> <?php  echo $p->title() ?></a>
<?php snippet('accordionmenu', array('subpages' => $p->children(), 'id' => $id)) ?> 
<?php $id+=1;}


 else { ?>
    <a class=" <?php echo ($p->isActive()) ? 'active' : '' ?>" href="<?php echo $p->url() ?>"><?php echo $p->title() ?></a>

<?php }
?>    
  </li>
  <?php endforeach;?>
</ul>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top