I am trying to make simple filtering with livewire in laravel but got stuck on the multiple category filters.
// Filters
public $filter = [
"title" => "",
"rangeFrom" => "",
"rangeTo" => "",
"order_field" => "order_by_name_asc",
"selectedCat" => [],
];
// method of query
else if(!empty($this->filter['selectedCat'])) {
$categories = explode(',', $this->filter['selectedCat']);
$products = Product::where('category_id',
function ($query) use ($categories) {
$query->whereIn('category_id', $categories);
})->limit($this->loadAmount)
->get();
}
// html[![enter image description here][1]][1]
<p class="mt-4">Catgegories</p>
@foreach ($categories as $cat)
<div class="flex" wire:key="{{ $cat->id }}">
<input type="checkbox" id="{{ $cat->title }}"
class="h-4 w-4 text-gray-700 border rounded mr-2"
wire:model="filter.selectedCat"
value="{{ $cat->id }}">
<label for="{{ $cat->title }}">{{ $cat->title }}</label>
</div>
@endforeach
What you're after can be achieved by binding to a dynamic
element in your selectedCat
nested array.
wire:model="filter.selectedCat.{{ $cat->id }}"
What this does is add an element to your array where the key
is the id
of the category
and value
is true, or false once it is unselected. The array keys
can then be used to determine which categories
to filter on, just need to remove the elements with a false
value.
Blade file
<div>
@foreach ($this->categories as $category)
<div class="flex items-center space-x-4 mb-2" wire:key="{{ $category->id }}">
<input type="checkbox" id="{{ $category->title }}" name="{{ $category->title }}"
wire:model="filters.categories.{{ $category->id }}" />
<label for="{{ $category->title }}">{{ $category->title }}</label>
</div>
@endforeach
<div class="grid grid-cols-4 gap-4">
@foreach ($this->results as $result)
<div>{{ $result->title }} ({{ $result->category->title }})</div>
@endforeach
</div>
</div>
Component
public $filters = [
'categories' => [],
];
public function getCategoriesProperty()
{
return Category::all();
}
public function getResultsProperty()
{
if (empty($this->filters['categories'])) {
return Product::all();
}
// this is where we remove the categories with a false value
$this->filters['categories'] = array_filter($this->filters['categories']);
return Product::whereIn('category_id', array_keys($this->filters['categories']))->get();
}
public function render()
{
return view('livewire.category-filter');
}