I have a category containing a collection of sheetitems and I'm trying to set an edit mode for a newly created sheetItem. I toggle this mode with alpine but i want to set the edit mode via a livewire component property also.
This is my delete component:
<div x-data="{showDeleteButton : false }" x-on:toggle-edit-mode-category-{{
$sheetItem->category->id }}.window="showDeleteButton = $event.detail.value">
<div x-show="showDeleteButton | $wire.showDeleteButton" class="mt-1">
<div wire:click="deleteSheetItem({{$sheetItem->id}})">
@include('components.balance.buttons.delete-image')
</div>
</div>
</div>
As you can see it is also visible on the following property:
$wire.showDeleteButton
So when i save an Item the following is triggered:
public function saveSheetItem()
{
$sheetItem = new SheetItem;
$sheetItem->name = $this->name;
$sheetItem->amount = Item::convertEurosToEuroCents($this->amount);
$sheetItem->category_id = $this->category->id;
$sheetItem->balance_id = $this->balance->id;
$sheetItem->save();
$this->resetForm();
$this->dispatch("sheet-item-saved", id: $sheetItem->id);
}
This triggers the update of my category ans thus my sheetitems in all categories ( planning on making that more specific also ). This triggers "sheet-item-saved". This triggers:
#[On('sheet-item-saved')]
#[On('sheet-item-deleted')]
#[On('updated-show-current-balance')]
public function updateCategory($id = null)
{
$sheetItemService = new SheetItemService();
$this->category = $sheetItemService->getCategoryWithSheetItems($this->category);
$this->getCurrentBalance();
$this->dispatch("sheet-item-created.{$id}");
}
The new Sheetitem is now created (it shows in the frondend) and another event is triggered to show the delete button for this sheetItem. This should be triggering:
#[On("sheet-item-created.{sheetItem.id}")]
function showDeleteButton()
{
Log::error($this->id());
$this->showDeleteButton = true;
}
But this is not triggered i'm doing it according to the documentation of livewire 3. Livewire Events
Can anyone see why it is not triggering? I tried hardcoding it like so with an id i know exists. That does fire. Could it be that the component does not exist at the time the event is fired?:
$this->dispatch("sheet-item-created.160");
#[On("sheet-item-created.160")]
I have also tried logging the different events but that shows a correct order. I did some more logging and there simply isn't a listener present when the event is fired. Al sheetItem Components respond except for the newly created one.
After some digging i fixed the issue. I did the following.
This is the view where the event is triggered and the sheetItem is generated. Notice ":show-delete-button="$sheetItem->showDeleteButton", This is a "modelable" property now.
<div x-data="{ ToggleEditMode : false }" id="{{ 'category-'.$category->id }}" class="card sheet-items-container">
<div class="flex justify-between card-sub-title">
<span class="font-bold w-full flex justify-between">
<div class="flex">
<div>
{{ $category->name }}
</div>
<div class="ml-3" x-on:click="$dispatch('toggle-edit-mode-category-{{ $category->id}}', {value: ToggleEditMode = !ToggleEditMode})">
<div x-show="!ToggleEditMode">
<x-balance.buttons.edit-button x-show="ToggleEditMode" wire:click="showDeleteButtons"/>
</div>
<div x-show="ToggleEditMode" wire:click="updateCategory">
<x-balance.buttons.save-button/>
</div>
</div>
</div>
<div x-show="ToggleEditMode">
@include('components.balance.buttons.delete-button-category')
</div>
</span>
</div>
<div class="sheet-items-list">
@foreach($category->sheetItems as $sheetItem)
<livewire:balance.sheet-items.sheet-item
:sheet-item="$sheetItem"
:show-delete-button="$sheetItem->showDeleteButton"
:key="'sheet-item-'.$sheetItem->id"/>
@endforeach
</div>
</div>
This is where the my delete component is included in " livewire:balance.sheet-items.sheet-item/":
<div x-bind:class="$wire.showCurrentBalance ? 'sheet-item-input-amount-income-day' : 'sheet-item-input-amount-no-income-day'"
class="flex place-items-center">
<div class="pt-1">€</div>
<x-input
wire:model.live="amount"
class="text-right"
type="text"
/>
<template x-if="!$wire.showCurrentBalance">
<div class="ml-1">
@include('components.balance.buttons.delete-button-sheet-item')
</div>
</template>
</div>
<template x-if="$wire.showCurrentBalance">
<div class="flex flex-row-reverse">
@include('components.balance.buttons.delete-button-sheet-item')
<div>
<div class="flex place-items-center justify-end">
<div class="pt-1 mr-1">€{{ $total }}</div>
</div>
</div>
</div>
</template>
This is my delete component, the key difference is that this changed from "showDeleteButton | $wire.showDeleteButton" to "$wire.showDeleteButton" and i changed it to:
x-on:toggle-edit-mode-category-{{ $sheetItem->category->id }}.window="$wire.showDeleteButton = $event.detail.value
So if i toggle it with alpine or set the property in my component the delete button will show:
<div x-data="{showDeleteButton : false }" x-on:toggle-edit-mode-category-{{ $sheetItem->category->id }}.window="$wire.showDeleteButton = $event.detail.value">
<div x-show="$wire.showDeleteButton" class="mt-1">
<div wire:click="deleteSheetItem({{$sheetItem->id}})">
@include('components.balance.buttons.delete-image')
</div>
</div>
This happens in the following order. A new sheetItem is saved:
public function saveSheetItem()
{
$sheetItem = new SheetItem;
$sheetItem->name = $this->name;
$sheetItem->amount = Item::convertEurosToEuroCents($this->amount);
$sheetItem->category_id = $this->category->id;
$sheetItem->balance_id = $this->balance->id;
$sheetItem->save();
$this->resetForm();
$this->dispatch("sheet-item-saved." . $sheetItem->category->id, id: $sheetItem->id);
}
The event is caught and for some reason the item is present in the sheetitems collection, i set the "showDeleteButton" property wich is "modelable", and the delete button shows:
#[On('sheet-item-saved.{category.id}')]
function addSheetItemToCategory($id)
{
$this->category->sheetItems->map(function ($sheetItem) use ($id) {
if ($sheetItem->id === $id) {
$sheetItem->showDeleteButton = true;
$sheetItem->total = Item::convertEuroCentsToEuros($sheetItem->count * $sheetItem->amount);
$sheetItem->amount = Item::convertEuroCentsToEuros($sheetItem->amount);
}
return $sheetItem;
});
}
It's a bit of a long story but maybe someone is helped with it.