I have created livewire components for shop page and product items in my project. here is my code
Shop page ,
`@extends('layouts.frontend-layout')
@section('content')
@livewire('product.index', ['category' => $category] , key("category-{$category->id}"))
@endsection
@section('script')
<script>
var priceSlider = document.getElementById('price-slider');
noUiSlider.create(priceSlider, {
start: [0, 50000],
behaviour: 'drag',
connect: true,
range: {
'min': 0,
'max': 100000
}
});
var FieldMin = document.getElementById('min-amount');
var FieldMax = document.getElementById('max-amount');
priceSlider.noUiSlider.on('update', function (values, handle) {
(handle ? FieldMax : FieldMin).innerHTML = values[handle];
});
</script>
@endsection`
Shop page Component
<?php
namespace App\Livewire\Product;
use App\Services\BrandService;
use App\Services\CategoryService;
use App\Services\ProductService;
use Livewire\Component;
class Index extends Component
{
public $brand;
public $category;
protected $productService;
protected $categoryService;
protected $bannerService;
protected $brandService;
public $filters = [
'brands' => [],
];
public function __construct()
{
$this->productService = new ProductService();
$this->categoryService = new CategoryService();
$this->brandService = new BrandService();
}
protected function queryString()
{
return [
'filters' => [
'as' => 'q'
],
];
}
public function mount($category)
{
$this->category = $category;
}
public function updatedFilters()
{
return view('livewire.product.index', [
'category' => $this->category,
'brands' => $this->brandService->all(),
'products' => $this->filterProducts($this->filters),
'sub_categories' => $this->category?->get('sub_categories', [])
]);
}
public function render()
{
return view('livewire.product.index', [
'category' => $this->category,
'brands' => $this->brandService->all(),
'products' => $this->filterProducts(),
'sub_categories' => $this->category?->get('sub_categories', [])
]);
}
public function filterProducts()
{
$filters = collect($this->filters);
$brandFilters = array_keys($filters->get('brands', []));
$subCategoryFilders = array_keys($filters->get('category', []));
$products = $this->category->get('products');
if (count($brandFilters)) {
$products = $products->filter(function ($item) use ($brandFilters) {
return !is_null($item['brand']) && in_array($item['brand']['slug'], $brandFilters);
});
}
return $products;
}
}
shop component view.
<div>
<div class="page-header py-4">
<div class="container container-wide">
<div class="row align-items-center justify-content-between">
<div class="col-lg-9 col-md-7 text-start">
<div class="breadcumb">
<ul>
<li><a href="/">Home <i class="fa-solid fa-chevron-right ms-1 me-2"></i></a></li>
<li><span>Shop</span></li>
</ul>
</div>
<h1 class="heading">{{$category?->get('name')}}</h1>
</div>
<div class="col-lg-3 col-md-5 text-end">
<div class="short">
<span>Sort By:</span>
<select class="form-select" name="sorts" wire:model.live="filters.sort">
<option selected>Price (Low to High)</option>
<option value="1">Relevance</option>
<option value="2">Newest</option>
<option value="3">Alphabetical</option>
<option value="4">Price (High to Loq)</option>
</select>
</div>
</div>
</div>
</div>
</div>
<div class="shop-section py-5">
<div class="container container-wide">
<div class="row">
<div class="col-lg-3 col-md-4 pe-lg-4 mb-4 mb-md-0">
<div class="shop-option">
<div class="price-range-box">
<div class="price-range mb-4">
<div class="option-heading">Price Range</div>
<div class="amount">LKR <span id="min-amount"></span> - <span id="max-amount"></span>
</div>
</div>
<div id="price-slider"></div>
</div>
<div class="selection-box">
<div class="option-heading mb-3">Brand</div>
@php
$brandsQuery = request()->query('q')['brands'] ?? [];
@endphp
<ul>
@foreach ($brands as $brand)
<li>
<div class="checkbox-group">
<input wire:model.live="filters.brands.{{$brand?->slug}}"
value="{{$brand?->slug}}" class="rounded-checkbox"
id="brand-{{$brand?->slug}}" type="checkbox" name="brands[]"
{{array_key_exists($brand?->slug, $brandsQuery) ? 'checked' : null}}>
<label for="brand-{{$brand?->slug}}">{{$brand?->name}}</label>
</div>
</li>
@endforeach
</ul>
</div>
<div class="selection-box">
<div class="option-heading mb-3">Categories</div>
<ul>
@foreach ($sub_categories as $subCat)
<li>
<div class="checkbox-group">
<input class="rounded-checkbox" id="{{$subCat?->get('slug')}}" type="checkbox"
name="sub-categories"
wire:model.live="filters.category.{{$subCat?->get('slug')}}"
value="{{$subCat?->get('slug')}}">
<label for="{{$subCat?->get('slug')}}">{{$subCat?->get('name')}}</label>
</div>
</li>
@endforeach
</ul>
</div>
</div>
</div>
<div class="col-lg-9 col-md-8">
<div class="row row-gap-30">
@if ($products)
@foreach ($products as $product)
<div class="col-lg-4 col-md-6 col-6">
@livewire('product.item-card', ['product' => $product], key('shop-product-'.$product->get('id')))
</div>
@endforeach
@endif
</div>
</div>
</div>
</div>
</div>
</div>
</div>
Product item component
<?php
namespace App\Livewire\Product;
use Livewire\Component;
class ItemCard extends Component
{
protected $product;
public function mount($product)
{
$this->product = $product;
}
public function render()
{
return view('livewire.product.item-card', ['product' => $this->product]);
}
}
Product item component view
@php
$image_1 = $product?->images?->first()->url ?? null;
$image_2 = $product?->images?->get(1)->url ?? null;
@endphp
<div class="product {{$product?->new ? 'new-badge' : null}}">
<a href="{{route('store.product', $product?->slug)}}" class="product-img">
<img src="{{ $image_1 }}" data-img="{{ $image_2 }}" class="swim" alt="Dankotuwa - {{$product?->name}}">
</a>
<div class="product-info">
<a href="{{route('store.product', $product?->slug)}}">
<div class="title"> {{$product?->name}} </div>
</a>
<div class="price my-3">
<span class="sell-price">Rs. {{number_format($product?->discount_price, 1)}}</span>
<span class="regular-price">Rs. {{number_format($product?->price, 1)}}</span>
</div>
<div class="product-btn">
<a type="button" class="btn btn-add-to-cart w-100">ADD TO CART</a>
<a type="button" class="btn btn-add-to-cart"><i class="icon-gift"></i></a>
</div>
</div>
</div>
When I'm filtering, I get message "Uncaught Snapshot missing on Livewire component with id: BIxBer9Dq6XeLwb3RQeE" and, exsisting javascript functions are not working.