I have categories like this:
I want to create a drop down menu for the categories, which I have successfully created. But the problem is that the child category is also shown as parent category whenever I click on the link.
See the below image:
I want Western category should appear only when Apparels category is clicked (which works perfectly fine) and it should not appear when clicked on the Categories link.
Category Model:
protected $fillable = [
'name', 'parent_id'
];
public function products()
{
return $this->belongsToMany('App\Product')->withTimestamps();
}
public function childs()
{
return $this->hasMany('App\Category', 'parent_id', 'id');
}
In Contoller:
$category = Category::where('parent_id', '!=', '0')->with('childs')->get();
The view:
<li class="dropdown">
Categories <span class="caret"></span>
<ul class="dropdown-menu multi-level" role="menu">
#foreach( $category as $cat )
<li #if($cat->childs->count()) class="dropdown-submenu" #endif>
<a class="links-titilium" href="{{ url( '/store/category', [$cat->id, Safeurl::make($cat->name)] ) }}" #if( $cat->childs->count() ) class="dropdown-toggle" data-toggle="dropdown" #endif>
{{ $cat->name }}
</a>
#if( $cat->childs->count() )
<ul class="dropdown-menu" role="menu">
<li>
#foreach( $cat->childs as $child )
<a href="{{url('/category', [Safeurl::make($cat->name), Safeurl::make($child->name)])}}">
{{ $child->name }}
</a>
#endforeach
</li>
</ul>
#endif
</li>
#endforeach
</ul>
</li>
$category = Category::where('parent_id', '!=', '0')->with('childs')->get();
as per your table rows above line will fetch all the categories. To fetch the categories with level 1 try the below line.
$category = Category::where('parent_id', '1')->with('childs')->get();
- Apparels
- Clothes
-- Western
or to fetch the top level categories with child categories
$category = Category::where('parent_id', null)->with('childs')->get();
- None
- Apparels
- Clothes
-- Western
I would try to make a condition right after the first foreach loop. It has to englobe the whole li so that it does not create the element if the array is at a child's index.
#foreach( $category as $cat )
#if($cat->parent_id == 1) /*this is the beginning of the if statement*/
<li #if($cat->childs->count()) class="dropdown-submenu" #endif>
<a class="links-titilium" href="{{ url( '/store/category', [$cat->id, Safeurl::make($cat->name)] ) }}" #if( $cat->childs->count() ) class="dropdown-toggle" data-toggle="dropdown" #endif>
{{ $cat->name }}
</a>
#if( $cat->childs->count() )
<ul class="dropdown-menu" role="menu">
<li>
#foreach( $cat->childs as $child )
<a href="{{url('/category', [Safeurl::make($cat->name), Safeurl::make($child->name)])}}">
{{ $child->name }}
</a>
#endforeach
</li>
</ul>
#endif
</li>
#endif /*this is the end of the if statement*/
#endforeach`
Related
I just want to know how create condition in laravel if url field / form in menus is true then in menu href will linked into $url, unless if url form is null, then in menu href will linked into $id just as usual.
my blade menu child :
<ul>
#foreach ($childs as $child)
<li>#if (count($child->childs)) #endif</li>
<li class="dropdown">
{{$child->nama}}#if (count($child->childs)) #endif
#if (count($child->childs))
#include('menuChild', ['childs'=> $child->childs])
#endif
</li>
#endforeach
</ul>
Try to change your code into this
<ul>
#foreach ($childs as $child)
<li><a #if (request($child->link, true))href="{{$child->link}}"#endif></a></li>
{{-- <li> #if (count($child->childs)) #endif</li> --}}
<li class="dropdown">
{{$child->nama}}#if (count($child->childs)) #endif
{{-- <li class="dropdown">#if (count($child->childs)) #endif --}}
#if (count($child->childs))
#include('menuChild', ['childs'=> $child->childs])
#endif
{{-- </li> --}}
</li>
#endforeach
</ul>
In my navbar I am showing the parent items. Which I am getting by using getItems() method. It is being linked to every item. And every parent item has some child items. Which I am getting using ($item->children as $child) And when one hovers over any parent item, the child items of that parent item should be visible from drop down.
The problem is whenever I hover around any item, every child item is being shown in the drop down. But I want only the child item of the parent item to be shown. The problem is likely with my #foreach loops. But I am not getting where. It would be nice If someone can help me out. Thanks in advance.
This is my blade file code.
<div class="navbar-list">
<div class="dropdown">
#foreach(getItems() as $item)
{{ $item->name }}
<div class="dropdown-menu">
#foreach ($item->children as $child)
<li class="dropdown-item" data-id="{{ $child->id }}" data-name="{{ $child->name }}">
<span>{{ $child->name }}</span>
</li>
#endforeach
</div>
#endforeach
</div>
</div>
And here is it's style
<style>
.dropdown:hover>.dropdown-menu {
display: block;
}
.dropdown>.dropdown-toggle:active {
pointer-events: none;
}
</style>
Every item in your first #foreach needs to be its own dropdown. Place <div class="dropdown"> inside your loop:
<div class="navbar-list">
#foreach(getItems() as $item)
<div class="dropdown">
{{ $item->name }}
<div class="dropdown-menu">
#foreach ($item->children as $child)
<li class="dropdown-item" data-id="{{ $child->id }}" data-name="{{ $child->name }}">
<span>{{ $child->name }}</span>
</li>
#endforeach
</div>
</div>
#endforeach
</div>
i have problem with display category and subcategories , i made this
in my blade
<div class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li class="active"><b class="fa fa-home"></b> Начало</li>
#foreach ($categories as $cat)
#foreach($subcategories as $sub)
#if($sub->parent_id == $cat->id)
<li class="dropdown ">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
{{$cat->name}} <i class="fa fa-caret-down"></i>
</a>
<ul class="dropdown-menu">
<li>{{ $sub->name }}</li>
</ul>
</li>
#endif
#endforeach
#endforeach
</ul>
</div>
</div>
</nav>
It show categories only when have one subcategory, i don't know why happend! Someone help me! (No bad votes please)
Here is my variables:
$categories = Category::where('parent_id', NULL)->get();
$subcategories = Category::where('parent_id','!=',NULL)->get();
The issue here is that you only create the list item within your foreach loop when there is a sub category aswell.
This example should do the trick for you.
<div class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li class="active"><b class="fa fa-home"></b> Начало</li>
#foreach ($categories as $cat)
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
{{$cat->name}} <i class="fa fa-caret-down"></i>
</a>
#foreach($subcategories as $sub)
#if($sub->parent_id == $cat->id)
<ul class="dropdown-menu">
<li>{{ $sub->name }}</li>
</ul>
#endif
#endforeach
</li>
#endforeach
</ul>
</div>
It is untested so let me know if it doesn't work.
I fixed it with little changes, but now work thanks #answered26
Here is my changes
<div class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li class="active"><b class="fa fa-home"></b> Начало</li>
#foreach ($categories as $cat)
<li class="{{ $cat->children->count() > 0 ? 'dropdown' : ''}}">
<a href="#" class="{{ $cat->children->count() > 0 ? 'dropdown-toggle' : '' }}" data-toggle="dropdown">
{{$cat->name}} {!! $cat->children->count() > 0 ? '<b class="fa fa-caret-down"></b>' : '' !!}
</a>
<ul class="dropdown-menu">
#foreach($subcategories as $sub)
#if($sub->parent_id == $cat->id)
<li>{{ $sub->name }}</li>
#endif
#endforeach
</ul>
</li>
#endforeach
</ul>
</div>
</div>
I have foreach loops in my blade where I show categories and sub-categories. This is the part from the blade
<div id="sidebar">
<h1>Categories</h1>
<ul class="nav nav-stacked cat-nav">
#foreach($menu as $category_menu)
#if($menu->has('subcategories'))
<li>
{{ $menu['category_name'] }}
<ul>
#if($menu->subcategories->count())
#foreach($menu->subcategories as $subcategory)
#if($subcategory->products->count())
<li>{{$subcategory->sub_cat_name}}</li>
#endif
#endforeach
#endif
</ul>
</li>
#else
<li><i class="fa fa-link"></i> <span>{{ $menu->category_name }}</span></li>
#endif
#endforeach
</ul>
</div>
This create folowing html
<ul class="nav nav-stacked cat-nav">
<li>
Category_1
<ul>
<li>
Sub Category in Category_1
</li>
</ul>
</li>
<li>
Category_2
<ul>
</ul>
</li>
</ul>
You can see the empty ul under Category_2 because Category_2 doesn't have any assigned sub-categories to it the ul element is empty. Maybe is easy fix but I've tried to play around with loops but can't fix it.
You have to move ul under if condition like:
#if($menu->subcategories->count())
<ul>
#foreach($menu->subcategories as $subcategory)
#if($subcategory->products->count())
<li>{{$subcategory->sub_cat_name}}</li>
#endif
#endforeach
</ul>
#endif
So that ul is generated when there is some data exist for it.
Edit: If still this is not working then change the condition from
$menu->subcategories->count()
to
count($menu->subcategories) > 0
You have to put <ul> inside #if($subcategory->products->count()) with a condition if it is already declared or not to prevent seperating all of the list in <ul></ul>. Then add </ul> condition after the loop.
#if($menu->subcategories->count())
#foreach($menu->subcategories as $subcategory)
<?php $ul = false; //Create a temporary variable to validate if <ul> is already declared ?>
#if($subcategory->products->count())
#if(!$ul)
<?php $ul = true; ?>
<ul>
#endif
<li>{{$subcategory->sub_cat_name}}</li>
#if($ul)
</ul> <!-- End ul here -->
#endif
#endif
#endforeach
#endif
In the controller you may add a new attribute to the $menu which will hold a boolean value whether any subcategory has products or not:
$menu->subcategoriesHaveProducts = $menu->subcategories->map(function($subcategory) use($menu) {
return !$subcategory->products->isEmpty() || $menu->subcategoriesHaveProducts;
});
After that you must change the if condition to check if the menu has any subcategory:
#foreach($menu as $category_menu)
#if($menu->has('subcategories'))
<li>
{{ $menu['category_name'] }}
#if($menu->subcategories->count() && $menu->subcategoriesHaveProducts)
<ul>
#foreach($menu->subcategories as $subcategory)
#if($subcategory->products->count())
<li>{{$subcategory->sub_cat_name}}</li>
#endif
#endforeach
</ul>
#endif
</li>
#else
<li><i class="fa fa-link"></i> <span>{{ $menu->category_name }}</span></li>
#endif
#endforeach
I am using laravel 5 as my framework.
I have a categories table like this:
I want to make it as a bootstrap menu with multi-level if the parent_id = id
This is what I have tried so far:
<ul class="nav navbar-nav navbar-right">
<li class="dropdown">
Categories <span class="caret"></span>
<ul class="dropdown-menu" role="menu">
#foreach( $category as $cat )
#if( $cat->id === $cat->parent_id)
<ul class="dropdown-menu" role="menu">
<li class="dropdown-submenu">
<a href="{{ url( '/category', Safeurl::make( $cat->name ) ) }}" data-toggle="dropdown-toggle" aria-expanded="false">{{ $cat->name }}
<ul class="dropdown-menu" role="menu">
<li>
</li>
</ul>
</a>
</li>
</ul>
#else
<li>
{{ $cat->name }}
</li>
#endif
#endforeach
</ul>
</li>
</ul>
But this results is, I get the output as 1 below the other.
I want that if the parent_id = id, it should show the sub category next to the that particular id.
For example, in the current example, id = 6 has the parent_id = 4, that means, the bootstrap menu should show the sub-category link next to the Clothing.
UPDATE 1:
After the answer submitted, I cannot display the sub category.
Here's the code for that:
<li class="dropdown">
Categories <span class="caret"></span>
<ul class="dropdown-menu" role="menu">
#foreach( $category as $cat )
<li #if($cat->childs->count()) class="dropdown" #endif>
<a href="javascript:void(0)" #if( $cat->childs->count() ) class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false" #endif>
{{ $cat->name }}
#if( $cat->childs->count() )
<span class="caret"></span>
#endif
</a>
#if( $cat->childs->count() )
<ul class="dropdown-menu" role="menu">
#foreach( $cat->childs as $child )
<a href="{{url('/category', [Safeurl::make($cat->name), Safeurl::make($child->name)])}}">
{{ $child->name }}
</a>
#endforeach
</ul>
#endif
</li>
#endforeach
</ul>
How do I achieve this ?
One way to do this is add a relation in your model
public function childs()
{
return $this->hasMany('Category', 'parent_id', 'id');
}
In your controller select just category where parent_id==0
And in your view you can ask for children:
#foreach( $category as $cat )
<li #if($cat->childs->count()) class="dropdown" #endif>
</span> #endif
#if($cat->childs->count())
<ul class="dropdown-menu" role="menu">
#foreach($cat->childs as $child)
<li></li>
#endforeach
</ul>
#endif
</li>
#endforeach