I have a table that displays records that is pulled from LiveWire component. When I click on a specific cell, the Save, Cancel buttons and an input box appear. When I click back on the buttons, I want the buttons and the text disappear but for some stranger reason, they stay there and nothing changes. The cell does gets saved but buttons and an inputbox still show. This is my code in a products.blade.php
<table class="w-full text-sm text-left rtl:text-right dark:text-gray-400">
<thead class="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">
<tr>
<th scope="col" class="px-6 py-3">Qty</th>
</tr>
</head>
<tbody>
<?php $i = 0 ?>
@foreach($products as $product)
<tr wire:key="{{$product->id}}" wire:poll class="odd:bg-white hover:bg-gray-50 odd:dark:bg-gray-900 even:bg-gray-50 even:dark:bg-gray-800 border-b dark:border-gray-700">
<td class="px-6 py-2 text-center" wire:click="editQty({{$product->id}})">
@if ($editProductID !== $product->id)
{{$product->p_qty}}
@else
<input type="text" wire:model.defer="productQty" class="bg-gray-100 test-gray-900 text-sm rounded block w-full p-2" />
<div class="flex items-center space-x-2">
<button type="button" wire:confirm="Are you sure?" wire:click="updateQty" class="text-blue-700 border border-blue-700 hover:bg-white-700 hover:text-white focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-full text-sm p-2 text-center inline-flex items-center dark:hover:text-white dark:focus:ring-blue-800 dark:hover:bg-blue-500">
<span class="sr-only">Edit</span>
</button>
<button type="button" wire:click="cancelEdit" class="text-blue-700 border border-blue-700 hover:bg-white-700 hover:text-white focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-full text-sm p-2 text-center inline-flex items-center dark:border-blue-500 dark:text-blue-500 dark:hover:text-white dark:focus:ring-blue-800 dark:hover:bg-blue-500">
<span class="sr-only">Cancel</span>
</button>
</div>
@error("productQty")
{{$message}}
@enderror
@endif
</td>
</tr>
@endforeach
</tbody>
<tfoot>
<tr class="font-semibold text-gray-900 dark:text-white">
<th colspan="5" scope="row" class="px-6 py-3 text-base">Total</th>
<td colspan="3" class="px-6 py-3">${{number_format($totalCost,0)}}</td>
<td class="px-6 py-3">{{$totalQty}}</td>
</tr>
</tfoot>
</table>
and on the component's side
public $editProductID = null;
#[Rule('required|min:1|max:3')]
public $productQty = null;
public function updateQty() {
$id = $this->editProductID;
$this->validateOnly('productQty');
Product::findOrFail($id)->update([
'p_qty' => $this->productQty
]);
$this->cancelEdit();
}
public function cancelEdit() {
$this->reset('editProductID','productQty');
}
public function editQty($id) {
$this->editProductID = $id;
$this->productQty = Product::findOrFail($id)->p_qty;
}
public function render()
{
$words = explode(' ', $this->search);
foreach($words as $key => $word) {
$words[$key] = 'keyword_build LIKE "%'.$word .'%" AND ';
}
$searchTerm = implode( ' ', $words);
$searchTerm = substr($searchTerm,0,-5);
if ($this->OnHand==1)
$sign = ">=";
else $sign = "<=";
$products = Product::whereRaw($searchTerm)
->where('p_qty', $sign , $this->OnHand)
->orderBy($this->sortBy, $this->sortDirection);
$totalQty = $products->sum('p_qty');
$totalCost = $products->sum('p_price');
$products = $products->paginate(perPage: 10);
return view('livewire.products',["products"=>$products, 'totalCost' => $totalCost, 'totalQty' => $totalQty]);
}
As you can see, when I click on the cell, the buttons and the inputbox do appear and I click on cancel or save, nothing happens even though it does go to a function called cancelEdit() which do set values to null.
A help would be greatly appreciated.
wire:click on the <td> element is activated also when you click on the elemets inside it, so the edit-mode is restarted also when you click Cancel. To avoid this we can add the self modifier:
<td class="px-6 py-2 text-center" wire:click.self="editQty({{$product->id}})">
in this way the clicks on the children elements are ignored
Also: with Livewire 3 wire:model is always deferred so you can safely remove .defer from wire:model