Search code examples
twitter-bootstraptreeaccordionnavkirby

Bootstrap accordion for nested navigation tree in Kirby


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>

Solution

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