I'm passing a paginated collection of products from my Livewire class into my Livewire component and it mostly works fine. However when I change page via the pagination (e.g. go from page 1 to page 2) I find that the currently hidden elements do not update.
For example, when I go to page 2 the <p>
containing the long description still shows the product->id from the corresponding product on page 1. However the <p>
containing the short description updates fine.
What am I doing wrong?
App/Livewire/ProductList.php
<?php
namespace App\Livewire;
use Livewire\WithPagination;
use Livewire\Component;
use App\Models\Product;
class ProductList extends Component
{
use WithPagination;
public function render()
{
$products = Product::paginate(20);
return view('livewire.product-list', [
"products" => $products,
]);
}
}
App/Resources/Views/Livewire/product-list.blade.php
<div class="grid grid-cols-4">
@foreach ($products as $product)
<div x-data="{expanded{{$product->id}}:false}" href="#">
<p x-show="!expanded{{$product->id}}">
{{$product->short_description}}
</p>
<a x-show="!expanded{{$product->id}}" x-on:click="expanded{{$product->id}}=true">
Read More
</a>
<p x-show="expanded{{$product->id}}">
{{$product->long_description}}
</p>
<a x-show="expanded{{$product->id}}" x-on:click="expanded{{$product->id}}=true">
Read Less
</a>
</div>
@endforeach
</div>
<div id="productPagination">
{{ $products->links() }}
</div>
Two things, first you need to ensure that your view contains only one root element. To achieve this I've wrapped the entire view in a div
.
Secondly, you need to provide a wire:key
to the root element within the loop, and provide it a unique value.
<div>
<div class="grid grid-cols-4">
@foreach ($products as $product)
<div x-data="{expanded{{$product->id}}:false}" wire:key="product-{{ $product->id }}">
<p x-show="!expanded{{$product->id}}">
{{$product->short_description}}
</p>
<a x-show="!expanded{{$product->id}}" x-on:click="expanded{{$product->id}}=true">
Read More
</a>
<p x-show="expanded{{$product->id}}">
{{$product->long_description}}
</p>
<a x-show="expanded{{$product->id}}" x-on:click="expanded{{$product->id}}=true">
Read Less
</a>
</div>
@endforeach
</div>
<div id="productPagination">
{{ $products->links() }}
</div>
</div>
Also href
is not a valid attribute on a div
tag.