How to list select option with multi level categories in Laravel 5 - 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!

Related

can foreach be filtered by id from foreign key?

So this is my code and my table
<li class="nav-item" role="presentation">
<a class="active show" data-bs-toggle="tab" data-bs-target="#menu-rice" aria-selected="false "role="tab">
<div>
<i class="fa-solid fa-bowl-rice"></i>
<h6>Rice</h6>
</div>
</a>
</li>
........
<div class="tab-pane fade active show" id="menu-rice" role="tabpanel">
<div class="tab-header text-center">
<h3>Rice</h3>
</div>
<div class="row">
#foreach ($ar_menu as $row)
<div class="col-lg-6 menu-item">
#empty($row->foto)
<img src="{{ url('/public/assets/img/menu/placeholder.jpg') }}"alt="Menu" class="menu-img">
#else
<img src="{{ url('/public/assets/img/menu')}}/{{$row->foto}}"alt="Menu" class="menu-img">
#endempty
<div class="menu-content">
{{ $row->nama }}<span>{{ $row->harga }}</span>
</div>
<div class="menu-ingredients ps-2">
{{ $row->ket }}
</div>
</div>
#endforeach
</div>
From Menu Table:
id
id_kategori
nama
harga
ket
foto
1
1
Fried Rice
40000
2
2
Chicken Buttermilk
40000
From Kategori Table:
id
nama
1
rice
2
chicken
So I want to filter a menu by it's category from menu table, so I want when id_kategori = 1 from menu tables it will show #menu-rice from code above, but I don't know how to make it :/ Any help will be appreciated
You can achieve this by multiple way. Here is one example
first add filter
<form action="{{url()->current()}}">
<select name="category_id" onchange="this.form.submit()">
#foreach($categories as $category)
<option value="{{$category->id}}">{{$category->name}}</option>
#endforeach
</select>
</form>
Then receive the category_id in controller and change the query like this
Menu::whereCategoryId($request->category_id)->get();
Return the result to view and show in loop.

Laravel8 Property [Eng2] does not exist on this collection instance

I am facing a strange problem: I have 2 pages with similar structure relating to same DB, the first one displaying a grid of products working perfectly, the second the item detail giving me this error. I can get the all JSON string {{$wine}} on the page but no way to extract elements with {{$wine->Eng2}} or {{$wine['Eng2']}}
#extends('layouts.layout')
#include('partials.sidebar')
<div class="detail-container">
<img src="/img/9122705276958.png" alt="" />
<ul>
<!--<li>{{$wine}}</li>-->
<li>{{$wine->Eng2}}</li>
<li></li>
</ul>
<!--<div class="addCart">
<i class="fas fa-shopping-cart"></i>
</div>
<ul class="side-icons">
<span><i class="fas fa-search"></i></span>
<span><i class="far fa-heart"></i></span>
<span><i class="fas fa-sliders-h"></i></span>
</ul>
</div>
<div class="bottom">
<ul>
<li></li>
<li></li>
</ul>
<ul class="price">
<li>Retail price: Ntd </li>
<li>Member price: Ntd </li>
<li>VIP price down to: Ntd </li>
</ul>
</div> -->
</div>
public function detail($id) {
$wine =Wine::where('ART','=',$id)->get();
return view('detail', [
'wine' => $wine
]);
}
Route::get('wines', [WineController::class,'index']);
Route::get('/wines/{id}',[WineController::class,'query']);
Route::get('detail/{id}', [WineController::class,'detail']);
Try to use
$wine = Wine::where('ART','=',$id)->first();
instead of
$wine = Wine::where('ART','=',$id)->get();
first() will get you the first element in the collection but get() will get you the whole collection, so you can use first() if the collection has one element, or you have to use foreach in the view.

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: 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?

select dropdown from options when options are in separate tags

I am a beginner in using webdriver and Here is the code with which i am working.
I want to click on a dropdown and again click on the list of values provided for that dropdown.
Please help me, i looked for other threads, but they are different.
<ul>
<li class="size select required">
<div id="dk_container_partNumber-55414" class="dk_container dk_theme_size dk_focus"
tabindex="" style="display: block;">
<a class="dk_toggle" style="width: 162px;">
<div class="dk_options">
<ul class="dk_options_inner">
<li class="dk_option_current">
<li class="">
<a data-dk-dropdown-value="605930243">S</a>
</li>
<li class="">
<a data-dk-dropdown-value="605930251">M</a>
</li>
<li class="">
<a data-dk-dropdown-value="605930260">L</a>
</li>
<li class="">
<a data-dk-dropdown-value="605930278">XL</a>
</li>
<li class="">
<a data-dk-dropdown-value="605930286">XXL</a>
</li>
</ul>
</div>
</div>
<select id="partNumber-55414" class="size-select" name="partNumber" style="display: none;">
<option data-property="CAT_SELECTSIZE" selected="selected" value="">Select Size</option>
<option value="605930243">S</option>
<option value="605930251">M</option>
<option value="605930260">L</option>
<option value="605930278">XL</option>
<option value="605930286">XXL</option>
</select>
I wish to select "S" and the same must be seen on the dropdown.
I am able to click on the dropdown and see the list of options using the below code :
driver.findElement(By.xpath("//(more xpath goes here)/ul/li[#class = 'size select required']/div/a/span")).click();
I tried the below code to select "S", but in vain :
Select SizeDropdown = new Select(driver.findElement(By.xpath("//(more xpath here)/ul/li[#class = 'size select required']/select")));
//driver.findElement(By.xpath("(//(more xpath here)/ul/li[#class = 'size select required']/select)/option[2]")).click();
//Below line gets and clicks the first option of Select Size 'S'
//SizeDropdown.getFirstSelectedOption().click();
//SizeDropdown.selectByVisibleText("S");
//SizeDropdown.selectByIndex(1);
//SizeDropdown.selectByValue("S");
I tried each command separately (after uncommenting),but could not see the "S" as the label of the dropdown as if it is selected by me.
Have you tried simplifying your xpath?
I use something like this to select an option from a drop down without first clicking to expand it:
Select select = new Select(driver.findElement(By.xpath("//select[#id='partNumber-55414']"));
select.selectByVisibleText("S");

Resources