Feb 8, 2024
0
Level 1
Livewire filter system with pivot
I have multiple tables. Product, Filter and pivot filter_product. If i click on one or two checkboxes, it shows to much products. I can't get the query working.
I hope somebody can help me with this filter function.
<?php
namespace Modules\Webshop\Http\Livewire;
use Livewire\Component;
use Modules\Categorie\Entities\Cat;
use Modules\Webshop\Entities\Product;
use Modules\Webshop\Entities\Filters as F;
use DB;
use Auth;
class Filter extends Component{
public $cats;
public $products;
public $geselecteerdeProducten = [];
public $search;
public $not = [];
public $filters = [];
public $checkboxes = [];
public $borders = [];
public $showGrid = true;
public $showList = false;
protected $listeners = ['refreshComponentFilter' => '$refresh', 'rCfilter' => 'rCfilter'];
public function mount(){
$this->cats = Cat::with('ca')->orderBy('nr', 'asc')->get();
if(isset($_COOKIE['filters'])){
$f = $_COOKIE["filters"];
$this->filters = json_decode($f);
foreach ($this->filters as $filter) {
$this->checkboxes[$filter] = true;
}
}
if(!empty($_COOKIE['filters'])){
$this->geselecteerdeProducten = json_decode($_COOKIE['filters']);
}
//dd($this->geselecteerdeProducten);
$this->rCfilter();
}
public function rCfilter(){
if(isset($_COOKIE['border'])){
$b = $_COOKIE["border"];
$this->borders = json_decode($b);
}
}
public function clear(){
setcookie('filters', '', time() + (86400 * 30), "/");
$this->geselecteerdeProducten = [];
$this->checkboxes = array_fill(0, count($this->checkboxes), false);
$this->dispatch('refreshComponentFilter');
}
public function sgrid(){
$this->showList = false;
$this->showGrid = true;
}
public function slist(){
$this->showList = true;
$this->showGrid = false;
}
public function toggleSelectie($productId){
if (in_array($productId, $this->geselecteerdeProducten)) {
$this->geselecteerdeProducten = array_values(array_diff($this->geselecteerdeProducten, [$productId]));
} else {
$this->geselecteerdeProducten[] = $productId;
}
setcookie('filters', json_encode($this->geselecteerdeProducten), time() + (86400 * 30), "/");
}
public function render(){
if(!empty($this->search)){
$this->products = Product::where('nr', 'like', '%' . $this->search . '%')
->orWhereHas('info', function ($query) {
$query->where('title', 'like', '%' . $this->search . '%')
//->orWhere('subtitle', 'like', '%' . $this->search . '%')
;
})
->get();
}else{
if (empty($this->geselecteerdeProducten)) {
$this->products = $products = Product::whereHas('info', function ($query) {
$query->where('published', 1);
})->take(25)->get();
} else {
$cat_id = F::whereIn('id', $this->geselecteerdeProducten)->pluck('cat_id')->toArray();
//dd($cat_id);
$cat_filters = F::whereIn('cat_id', $cat_id)
->whereNotIn('id', $this->geselecteerdeProducten)
->pluck('id', 'id');
$this->not = DB::table('ws_filter_product')
->whereIn('filter_id', $cat_filters)
->pluck('product_id')
->unique();
$this->products = Product::whereHas('info', function ($query) {
$query->where('published', 1);
})->whereNotIn('id', $this->not)->get();
}
}
return view('webshop::livewire.filter',[
'products' => $this->products,
]);
}
}
my blade
<div>
<div class="row mt-2">
<div class="col-lg-3 order-2 order-lg-1">
<div class="card">
<div class="card-header">
{{__('Filters')}}
</div>
<div class="card-body">
<div class="text-end text-primary" wire:click="clear" wire:key="clear">{{__('Clear filters')}}</div>
@foreach($cats as $cat)
<strong wire:key="cats_{{$cat->id}}">{{$cat->info->title}}</strong><br/>
@foreach($cat->ca as $ca)
<input type="checkbox" class="ms-3" wire:key="cat-{{$ca->id}}" wire:model="checkboxes.{{$ca->id}}" wire:click="toggleSelectie({{ $ca->id }})" > {{$ca->title}}<br/>
@endforeach
<br/>
@endforeach
</div>
</div>
</div>
<div class="col-lg-9 order-1 order-lg-2">
<div class="row m-0 p-0">
<div class="col-9 p-0 col-md-10">
<input type="text" class="form-control" wire:model.live="search" wire:key="search" placeholder="{{__('Search')}}"/>
</div>
<div class="col-3 text-end p-0 col-md-2">
<div class="btn {{($showGrid == 1 ? 'btn-primary' : 'btn-outline-primary')}} h4" wire:click="sgrid" wire:key="sgrid"><i class="bi bi-grid-3x3-gap"></i></div>
<div class="btn {{($showList == 1 ? 'btn-primary' : 'btn-outline-primary')}} h4" wire:click="slist" wire:key="slist"><i class="bi bi-list"></i></div>
</div>
</div>
@if($showGrid)
<div class="row row-cols-1 row-cols-md-4 g-4 mt-2">
@foreach($products as $prod)
<div class="col" wire:key="prod_grid_{{$prod->id}}">
<div class="col card h-100 rounded-0 product {{(isset($_COOKIE['border']) && (in_array($prod['id'], $borders)) ? 'border-danger border-2' : '')}}">
<a href="{{route('products', [$prod->cat->info->slug, $prod->info->first()->slug])}}" class="text-decoration-none text-white text-center">
<div class="position-relative">
<img src="{{($prod->front_image == null ? asset('modules/auth/img/logo.png') : asset('img/products/front/thumb/'.$prod->front_image))}}" alt="{{$prod->info->first()->title}}" class="card-img-top">
<div class="price">€ {{number_format($prod->price, 2, ',', ' ')}}</div>
@if($prod->out_of_stock == 1)
<div class="soldout">{{__('Sold out')}}</div>
@endif
</div>
</a>
<div class="card-body">
<h5 class="card-title">{!!$prod->info->first()->title!!}</h5>
<p class="card-text"><small>{{$prod->info->first()->subtitle}}</small></p>
@foreach($prod->filter as $filter)
<span class="badge text-bg-primary">{{$filter->title}}</span>
@endforeach
</div>
<div class="card-footer p-0">
<small>
<livewire:webshop::cart-quantity :product="$prod" wire:key="grid_{{$prod->id}}"/>
</small>
</div>
</div>
</div>
@endforeach
</div>
@else
@foreach($products as $prod)
<div class="card mb-3 {{(isset($_COOKIE['border']) && (in_array($prod['id'], $borders)) ? 'border-danger border-2' : '')}}" wire:key="prod_list_{{$prod->id}}">
<div class="row g-0">
<div class="col-md-2">
<a href="{{route('products', [$prod->cat->info->slug, $prod->info->first()->slug])}}" class="text-decoration-none text-white text-center">
<img src="{{($prod->front_image == null ? asset('modules/auth/img/logo.png') : asset('img/products/front/thumb/'.$prod->front_image))}}" alt="{{$prod->info->first()->title}}" class="img-fluid rounded-start">
</a>
</div>
<div class="col-md-10">
<div class="card-body">
<a href="{{route('products', [$prod->cat->info->slug, $prod->info->first()->slug])}}" class="text-decoration-none text-black">
<h5 class="card-title ">{!!$prod->info->first()->title!!}</h5>
<p class="card-text">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam id mollis arcu. Donec laoreet, odio ultricies venenatis aliquet, ligula enim tristique nibh, ac blandit est tellus at tellus. Suspendisse potenti. Nullam faucibus id nulla eget tincidunt. Sed imperdiet faucibus tellus.</p>
</a>
<p class="card-text">
<small class="row">
<livewire:webshop::cart-quantity :product="$prod" wire:key="list_{{$prod->id}}"/>
</small>
</p>
</div>
</div>
</div>
</div>
@endforeach
@endif
</div>
</div>
</div>
Please or to participate in this conversation.