My Livewire component has two tables. When I click on one of the anchor tags, the table underneath gets updated, but at the same time, the last column of the second table gets overwritten.
<div>
<div class="bg-white text-black rounded-xl border pl-4 pr-4 pt-2 pb-2 mt-2 flex justify-between">
<div class="bg-black text-white text-bold flex-1 p-1 rounded-xl mr-4 font-bold flex justify-evenly">
<a href="#" wire:click.prevent="showFavoritesForLastDays(1)" class="text-white">Heute</a>
<a href="#" wire:click.prevent="showFavoritesForLastDays(7)" class="text-white">7</a>
<a href="#" wire:click.prevent="showFavoritesForLastDays(30)" class="text-white">30 Tage</a>
<a href="#" wire:click.prevent="showFavoritesForLastDays(365)" class="text-white">1 Jahr</a>
<a href="#" wire:click.prevent="showFavoritesForLastDays(10950)" class="text-white">Max</a>
</div>
<div class="bg-black text-white text-bold flex-1 p-1 rounded-xl font-bold flex justify-evenly">
<a href="#" wire:click.prevent="showWorstForLastDays(1)" class="text-white">Heute</a>
<a href="#" wire:click.prevent="showWorstForLastDays(7)" class="text-white">7</a>
<a href="#" wire:click.prevent="showWorstForLastDays(30)" class="text-white">30 Tage</a>
<a href="#" wire:click.prevent="showWorstForLastDays(365)" class="text-white">1 Jahr</a>
<a href="#" wire:click.prevent="showWorstForLastDays(10950)" class="text-white">Max</a>
</div>
</div>
<div class="bg-white text-black rounded-xl border p-4 mt-2 flex justify-between">
@if(count($top10Up) > 0)
<table id="favorite10" class="table table-striped mr-4">
<th class="w-1/12">#</th>
<th class="w-2/12"></th>
<th class="w-6/12">{{ __('Name') }}</th>
<th clas="w-3/12"># đź‘Ť</th>
@foreach($top10Up as $upItem)
<tr>
<td>{{ $loop->iteration }}</td>
<td><img class="h-10 w-10 dropshadowimgsmall" src="{{ $upItem['picture'] }}"
alt="{{ $upItem['name'] }}"></td>
<td>{{ $upItem['name'] }}</td>
<td id="x1">{{ $upItem['totalVotesUp'] }}</td>
</tr>
@endforeach
</table>
@else
<div class="w-full m-4">Es wurden keine Stimmen im gewählten Zeitraum abgegeben</div>
@endif
@if(count($top10Down) > 0)
<table id="hated10" class="table table-striped">
<th class="w-1/12">#</th>
<th class="w-2/12"></th>
<th class="w-6/12">{{ __('Name') }}</th>
<th clas="w-3/12"># đź‘Ž</th>
@foreach($top10Down as $downItem)
<tr>
<td>{{ $loop->iteration }}</td>
<td><img class="h-10 w-10 dropshadowimgsmall" src="{{ $downItem['picture'] }}"
alt="{{ $downItem['name'] }}"></td>
<td>{{ $downItem['name'] }}</td>
<td id="x2">{{ abs($downItem['totalVotesDown']) }}</td>
</tr>
@endforeach
</table>
@else
<div class="w-full m-4">Es wurden keine Stimmen im gewählten Zeitraum abgegeben</div>
@endif
</div>
</div>
Why is this happening and how can I fix it?
2
Answers
The reason for this behaviour is when loops are used for rendering information in Livewire component, It doesn’t know how to keep track of each element inside the loop uniquely. Especially for the elements with dynamic content. So when you call an update function on either of the tables, Livewire struggles to find the correct element to overwrite, resulting in wrong dom manipulation.
You must add wire:key attribute to the elements inside the loop, that will directly tell Livewire how to keep track of each DOM element. Which will eventually solve your problem.
The value to wire:key must be unique across the page. So Your loops should be updated like this:
Your problem is two-fold. First problem is that your two tables has elements where the ID attributes is not unique.
Remove these two from your two tables,
Secondly, on the
<tr>
element in each of the two tables, you should specify awire:key
with a unique value to it, that will be unique across the page, like this (I’m assuming that you have an ID attribute on your collection that’s unique to that row),You don’t need any nested keys in the subsequent
<td>
element, and you should not use$loop->index
or$loop->iteration
as part of the unique wire:key.