Search code examples
twitter-bootstraplaravelforeachlaravel-bladenested-sets

Laravel - Creating bootstrap dropdown for each parent in a nested set


I am using etrepat/baum to create the categories for my application in a laravel project. I have a problem when using @foreach in blade when I want to create bootstrap dropdown menus for the categories. This works just fine when the structure is like so:

<nav id="nav2" role="navigation">
  <ul class="nav navbar-nav">
    <li class="dropdown">
      <a href="#" class="dropdown-toggle" data-toggle="dropdown">Shop by Category<span class="caret"></span></a>
      <ul class="dropdown-menu" role="menu">
        @foreach($catnav as $cat) @if($cat->depth == 0)
        <li>
          {{ HTML::link(URL::action('StoreController@getCategories', [$cat->slug]), $cat->name) }} @else($cat->depth == 1)
          <ul>
            <li><a href="{{ URL::to('/store/categories/' . implode('/', $cat->getAncestorsAndSelf()->lists('slug'))) }}">{{$cat->name}}</a>
            </li>
          </ul>
        </li>
        @endif @endforeach
      </ul>
    </li>
  </ul>
</nav>

This is the output to the above:

enter image description here

But I don't want to have a Shop by Category dropdown, but I am trying to make a dropdown for each of the parent categories to contain the children in the dropdown-menu. I tried this structure, but the @foreach will mess with the layout.

<nav id="nav2" role="navigation">
  <ul class="nav navbar-nav">
    @foreach($catnav as $cat) @if($cat->depth == 0)
    <li class="dropdown">
      <a href="#" class="dropdown-toggle" data-toggle="dropdown">{{ HTML::link(URL::action('StoreController@getCategories', [$cat->slug]), $cat->name, array('class'=>'dropdown-toggle' ,'data-toggle'=>'dropdown')) }}<span class="caret"></span></a>
      @else($cat->depth == 1)
      <ul class="dropdown-menu" role="menu">
        <li><a href="{{ URL::to('/store/categories/' . implode('/', $cat->getAncestorsAndSelf()->lists('slug'))) }}">{{$cat->name}}</a>
        </li>
        @endif
      </ul>
    </li>
    @endforeach
  </ul>
</nav>

How can I achieve this?


Solution

  • After a long day trying to figure this out I ended up:

    • Using the toHierarchy() method to return a nested collection of the queried tree.

    • Using a @foreach loop to get all the parent nodes and inside another @foreach to get the children.

    • Using the isRoot() function to check if the item is a parent.

    • Using isLeaf() function to check if is the end of a branch.

    • Using lots of @if statements.

    Solution:

    <nav id="nav2" role="navigation">
        <ul class="nav navbar-nav">
        @foreach($catnav as $item)
            <li @if($item->isRoot())class ="dropdown"@endif>
                @if(!$item->isLeaf())
                    <a @if($item->isRoot()) class="dropdown-toggle"@endif href="/store/categories/{{ $item->slug }}">
                    {{ $item->name }}
                    @if($item->isRoot()) <span class="caret"></span> @endif
                    </a>
                @else
                    <a href="/store/categories/{{ $item->slug }}">{{$item->name}}</a>
                @endif
                @if($item->isRoot() && !$item->isLeaf())
                <ul class="dropdown-menu">
                    @foreach($item->children as $child)
                      <li><a href="{{ URL::to('/store/categories/'.implode('/', $child->getAncestorsAndSelf()->lists('slug'))) }}">{{$child->name}}</a></li>
                    @endforeach
                </ul>
                @endif
            </li>
        @endforeach
        </ul>
    </nav>