Is Nested GroupBy supported in Laravel? - laravel

I have a categories table with the fields "id", "category_id", "name" where "category_id" is the id of the parent category. My requirement is that I need to group the categories like below.
Europe
- England
Asia
- India
- Kerala
- Kochi
Note - Here Europe,England,Asia,India,Kerala,Kochi are categories. Asia is the parent category of India and India is the parent category of Kerala and Kerala is the parent category of Kochi.
Is there some nested groupBy solution?

Assuming that it's a one-to-many self-referencing relationship i.e. one category can only belong to some other category (single parent)
And your Category model should look something like this:
public function parent() {
return $this->belongsTo('App\Category');
}
public function children() {
return $this->hasMany('App\Category');
}
In your main blade template, you have:
<ul class="navbar-nav">
#foreach ($menu_items as $item)
#include('menu', $item)
#endforeach
</ul>
Where $menu_items is the list of all parent categories ( categories where category_id is null or 0 )
And your menu blade template:
#if ( $item->children->isNotEmpty() )
<li class="nav-item {{ $item->parents->isNotEmpty() ? 'dropdown-submenu' : 'dropdown' }}">
<a class="nav-link dropdown-toggle" href="{{ $item->slug ? url($item->slug) : 'javascript:void(0);' }}" id="navbarDropdown{{ $item->id }}" role="button" data-toggle="hover">
{{ $item->title }}
</a>
<ul class="dropdown-menu" aria-labelledby="navbarDropdown{{ $item->id }}">
#foreach ($item->children as $item)
#include('menu', $item)
#endforeach
</ul>
#else
<li class="nav-item">
<a class="nav-link" href="{{ $item->slug ? url($item->slug) : 'javascript:void(0);' }}">{{ $item->title }}</a>
#endif
</li>
I literally pasted this code from a project I worked on recently to give you an idea about nested drop-down, you've to work on the styling part yourself. But this code is enough to give you a proper understanding.
PS: this all untested. let me know if something doesn't work

Related

Set Current Category to Active in laravel

i am trying to Set Current Category to active when i reload my page but unfortunately it's not working please help me thanks.
html view
<ul class='visible-links nav nav-tabs' role="tablist">
#foreach($productCategories as $productCategory)
<li>
<a class="tab-a active-a productcategory {{ Request::is('') ? 'active' : '' }}" data-id="{{$productCategory->id}}" data-toggle="tab" href="{{$productCategory->id}}" role="tab" data-toggle="tab">{{$productCategory->name}}
</a>
</li>
#endforeach
</ul>
Route
Route::get('products/get-product', 'ProductController#getproduct')->name('products.getproduct');
Route::get('/products/{slug}', 'ProductController#index')->name('products');
you can try this :
assuming this is from route Route::get('/products/{slug}'...
<ul class='visible-links nav nav-tabs' role="tablist">
#foreach($productCategories as $productCategory)
<li>
<a class="tab-a active-a productcategory
{{ request()->route('slug') == $productCategory->slug ? 'active' : '' }}"
data-id="{{$productCategory->id}}" data-toggle="tab" href="{{$productCategory->id}}"
role="tab" data-toggle="tab">{{$productCategory->name}}
</a>
</li>
#endforeach
</ul>
//Request::route() or the helper request()->route()
if you are using model binding in the controller you can use request()->route('slug')->id == $productCategory->id
make sure that active class is triggering active tab, or else the active-a is the class triggering active tab

I am trying to click on a category and products will show accordingly, but its not working

Controller:
public function shopfront(){
$products=Product::all();
$categories=Category::all();
return view('shop.index',compact('products','categories'));
}
index.blade.php:
<div class="sidebar-widget">
<h4 class="pro-sidebar-title">Categories</h4>
<div class="sidebar-widget-list mt-30">
<ul>
#foreach ($categories as $category)
#foreach ($products as $product)
#if ($category->id==$product->category->id)
<li>
<div class="sidebar-widget-list-left">
<input type="checkbox"> <a href="">{{ $category->name }}
{{-- <span>4</span> --}}
</a>
<span class="checkmark"></span>
</div>
</li>
#endif
#endforeach
#endforeach
</ul>
</div>
</div>
I do not know how to achieve this, will highly appreciate some help or i sample that i can work with
Image
i don't know how you want to achieve it but let me give you an idea if you want it in this way:
when click on a category then it should show all products of that category:
in your blade file
#foreach($categories as $category)
<li class="nav-item">
<a class="nav-link" href="{{route('category.products',$category->name)}}"> {{$category->name}}</a>
</li>
#endforeach
you should create a route named category.products as below in web.php
Route::get('category/{name}','YourController#yourmethod')->name('category.products');
controller
public function CategoryProducts($name){
$category = Category::where('name',$name)->first();
$products = $category->products;
return view('front-end.categoryWise-products',compact('products'));
}
you can customize it according to your requirements.

Laravel - Trying to get property 'name' of non-object

Im making a view that shows the users and the companies they work for.
In my User model i return the view like this:
return view('users.index', ['users' => $model->all()]);
The model $model->all() is my User model.
Then in my index.blade file i loop through the data like this:
#foreach ($users as $user)
<tr>
<td>{{ $user->name }}</td>
<td>
{{ $user->email }}
</td>
<td>{{ $user->created_at->format('d/m/Y H:i') }}</td>
<td>{{ $user->company->name }}</td>
<td class="text-right">
<div class="dropdown">
<a class="btn btn-sm btn-icon-only text-light" href="#" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="fas fa-ellipsis-v"></i>
</a>
<div class="dropdown-menu dropdown-menu-right dropdown-menu-arrow">
#if ($user->id != auth()->id())
<form action="{{ route('user.destroy', $user) }}" method="post">
#csrf
#method('delete')
<a class="dropdown-item" href="{{ route('user.edit', $user) }}">{{ __('Edit') }}</a>
<button type="button" class="dropdown-item" onclick="confirm('{{ __("Are you sure you want to delete this user?") }}') ? this.parentElement.submit() : ''">
{{ __('Delete') }}
</button>
</form>
#else
<a class="dropdown-item" href="{{ route('profile.edit') }}">{{ __('Edit') }}</a>
#endif
</div>
</div>
</td>
</tr>
#endforeach
But when i try to show $user->company->name i get the following error:
Trying to get property 'name' of non-object
I tried debugging by using dd($user->company) and it showed all the company information of the company connected to the user. Then i tried dd($user->company->name) and it showed the company name.
I dont understand why i cant just show $user-company->name without getting the error but when i dd($user->company->name) it shows the company name.
Can someone point me in the right direction.
It probably shows an error because one of your users doesn't have a company. The first one of your loop has one, that's why when you dd($user->company), you see a company. But it doesn't mean the second or third has one. You can do a if statement in order to catch any null company. Something like
if($user->company == null){
dd($user);
}
Alternatively, you can just do dd($users->pluck('company','id'));, which will show you a collection with the user id as key and related company (or null) as value.
You can use optional() helper to solve this. There are users who don't have companies. SO you can display them like this optional($user->company)->name and you will not get an error if a user does not have a company
If you are trying to get relationship object value might be chances are there you will get this type of error. Due to there is some user who doesn't have company detail.
Just try below code.
{{ #$user->company->name }}

Laravel: Filter threads by clickable categories

I made a page with a categories list on the left and threads on the right side. List of categories are dynamically displayed with CRUD in different controller as threads. And all that works.
ForumThread controller index method:
public function index()
{
$threads = ForumThread::orderBy('id', 'desc')->paginate(10);
$categories = ForumCategory::with('threads')->get();
return view('forum.thread.index', compact('threads', 'categories'));
}
threads belongs to categories of course and view with categories part look like this:
<div class="col-md-3">
<ul class="list-group">
<a href="{{route('forum.index')}}" class="list-group-item">
<span class="badge">{{$threads->count()}}</span>
All categories
</a>
#foreach ($categories as $category)
<a href="#" class="list-group-item">
<span class="badge">{{$category->threads->count()}}</span>
{{$category->name}}
</a>
#endforeach
</ul>
</div>
The thing I want is to set a href link to go to threads that belongs to that specific category that is clicked.
I presume that I need a new method for this (I presume because I don't know how to make this happened in index method) so I made one:
public function showThreads($id)
{
$showThreads = ForumCategory::with('threads')->findOrFail($id);
return view('forum.thread.index', compact('showThreads'));
}
route:
Route::get('/forum/category/{id}', 'ForumThreadController#showThreads')->name('category.threads');
and when I set id for example '/forum/category/3' and try function dd(showThreads->thread); it shows me an array of threads which belongs to that category id.
But now I don't know how to implement this in this foreach loop that already working for category list. I tried like this:
<div class="col-md-3">
<ul class="list-group">
<a href="{{route('forum.index')}}" class="list-group-item">
<span class="badge">{{$threads->count()}}</span>
All categories
</a>
#foreach ($categories as $category)
<a href="{{ route('category.threads', $showThreads->id) }}" class="list-group-item">
<span class="badge">{{$category->threads->count()}}</span>
{{$category->name}}
</a>
#endforeach
</ul>
</div>
but it shows me error: Undefined variable: threads
Any help?

How to list select option with multi level categories in Laravel 5

I have a question. Before asking this question I have searched a lot but I did not found any workable example, so I have put my question here. I have a concept of parent child relationship with in the same table for example, I have table category like this:
id int auto_increment primary
name varchar
type varchar
parentid int
Now I want to generate select box with multi level option like:
<select class="category" name="category">
<option value="-1">Select Category</select>
<optgroup value="0" label="Parent Tag">
<option value="1">Child Tag</option>
<option value="2">Child Tag</option>
</optgroup>
<optgroup value="3" label="Parent Tag">
<option value="4">Child Tag</option>
<option value="5">Child Tag</option>
</optgroup>
</select>
I also want to generate Menus same as above.
<ul>
<li>Menu 1</li>
<li>
Menu 2
<ul class="dropdown">
<li>Menu 1 of 2</li>
<li>Menu 2 of 2</li>
<li>Menu 3 of 2</li>
</ul>
</li>
<li>Menu 3</li>
<li>
menu 4
<ul class="dropdown">
<li>Menu 1 of 4</li>
<li>Menu 2 of 4</li>
<li>Menu 3 of 4</li>
</ul>
</li>
</ul>
Please friends help to achieve this functionality in laravel 5. Depth for this is not limited and it can be 2, 3, 4; as many as the user wants to add.
Model
class Category extends Model{
...
public function parent()
{
return $this->belongsTo('App\Models\Category', 'parentid');
}
public function children()
{
return $this->hasMany('App\Models\Category', 'parentid');
}
}
In Controller
$categories = Category::with('children')->select('name', 'id','parentid')->where('configtype','=','Category')->get();
return view('admin.category.index',['pageTitle' => 'Category', 'configlist' => $categories]);
In view
?
For the ul you can create a recursive function using blade e.g.
#include('partials.menu', $items)
Then in that view something like:
<ul>
{{-- You would have to provide your own logic to decide which class name the ul should have --}}
#foreach($items as $item)
{{ $item->name }}
#if(!empty($item->children)) {{-- Or however you want to check for children --}}
#include('partials.menu', ['items' => $item->children]) {{-- Here I am just telling blade to treat the children as $items where they are passed through --}}
#endif
#endforeach
</ul>
This is a basic implementation of a recursive function with blade.
You can use a similar approach for the select as well.
Hope this helps!

Resources