Hello !
I've some problems with Livewire, I'm new to deal with it and I've created a project for learn and practice Livewire.
I've created a Livewire component "ManageSites", I want to make a CRUD with my Site model inside this component, I've created table and I use some modals for create, edit and delete.
In the create / edit modal, I've added a form (input text and input checkbox), here all going succeed, but when I change an input (checkbox checked to checkbox unchecked) my modal close automatically, it's not my intention and I don't understand what going on...
Here a video for my problem: https://streamable.com/l3mb4j
ManageSite.php
<?php
namespace App\Http\Livewire;
use App\Models\Site;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;
use Livewire\Component;
class ManageSites extends Component
{
public bool $showCreateModal, $showConfirmDeleteModal = false;
public $state = [];
public bool $updateMode = false;
public function openCreateModal()
{
$this->showCreateModal = true;
}
public function store()
{
Validator::make($this->state, [
'domain' => 'required',
'is_active' => 'nullable',
])->validate();
Auth::user()->sites()->save(new Site([
'domain' => $this->state['domain'],
'is_active' => isset($this->state['is_active']) && $this->state['is_active'] ? 1 : 0,
]));
$this->reset('state');
$this->showCreateModal = false;
}
public function openEditModal(int $id)
{
$this->updateMode = true;
$site = Auth::user()->sites()->findOrFail($id);
$this->state = $site->toArray();
$this->showCreateModal = true;
}
public function update()
{
Validator::make($this->state, [
'is_active' => 'nullable',
])->validate();
$site = Auth::user()->sites()->findOrFail($this->state['id']);
$site->update([
'is_active' => isset($this->state['is_active']) && $this->state['is_active'] ? 1 : 0,
]);
$this->showEditModal = false;
$this->reset('state');
$this->updateMode = false;
}
public function confirmDelete(int $id)
{
$site = Auth::user()->sites()->findOrFail($id);
$this->state = $site->toArray();
$this->showConfirmDeleteModal = true;
}
public function delete()
{
$site = Auth::user()->sites()->findOrFail($this->state['id']);
$site->delete();
$this->showConfirmDeleteModal = false;
}
public function render()
{
return view('livewire.manage-sites')
->with('sites', Auth::user()->sites()->get());
}
}
manage-site.blade.php
<div>
<x-utils.button class="bg-blue-400 hover:bg-blue-500" wire:click="$set('showCreateModal', true)">
Créer un site
</x-utils.button>
<table>
<thead>
<tr>
<th>Domain</th>
<th>Active</th>
<th>Created at</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
@foreach($sites as $site)
<tr>
<td>{{ $site->domain }}</td>
<td>{{ $site->is_active ? 'Oui' : 'Non' }}</td>
<td>{{ $site->created_at }}</td>
<td>
<x-utils.button class="bg-gray-400 hover:bg-gray-500" wire:click="openEditModal({{ $site->id }})">
Edit
</x-utils.button>
<x-utils.button class="bg-red-400 hover:bg-red-500" wire:click="confirmDelete({{ $site->id }})">
Delete
</x-utils.button>
</td>
</tr>
@endforeach
</tbody>
</table>
<!-- START - Create Modal -->
<x-utils.modal wire:model="showCreateModal">
<x-slot name="header">
@if($updateMode)
<h1>Edit</h1>
@else
<h1>Create</h1>
@endif
</x-slot>
<x-slot name="main">
<form>
@if(!$updateMode)
<label for="domain">Domain</label>
<input id="domain" type="text" wire:model="state.domain">
@endif
<label for="active">Active</label>
<input id="active" type="checkbox" wire:model="state.is_active">
</form>
</x-slot>
<x-slot name="footer">
@if($updateMode)
<x-utils.button class="bg-blue-400 hover:bg-blue-500" wire:click="update">Edit</x-utils.button>
@else
<x-utils.button class="bg-blue-400 hover:bg-blue-500" wire:click="store">Create</x-utils.button>
@endif
</x-slot>
</x-utils.modal>
<!-- END - Create Modal -->
<!-- START - Delete Modal -->
<x-utils.modal wire:model="showConfirmDeleteModal">
<x-slot name="header">
<h1>Delete</h1>
</x-slot>
<x-slot name="main">
<p>Are you sure ?</p>
</x-slot>
<x-slot name="footer">
<x-utils.button class="bg-gray-400 hover:bg-gray-500" wire:click="$set('showConfirmDeleteModal', false)">
Cancel
</x-utils.button>
<x-utils.button class="bg-red-400 hover:bg-red-500" wire:click="delete">Delete</x-utils.button>
</x-slot>
</x-utils.modal>
<!-- END - Delete Modal -->
</div>
And my modal component
<div {{ $attributes }}
x-data="{ show : @entangle($attributes->wire('model')) }"
x-show="show"
style="display: none"
>
<div class="fixed inset-0 bg-gray-900 opacity-90" x-on:click="show = false"></div>
<div class="bg-white shadow-md p-4 max-w-sm h-48 m-auto rounded-md fixed inset-0">
<div class="flex flex-col h-full justify-between">
<header class="font-bold text-lg">
{{ $header }}
</header>
<main class="mb-4">
{{ $main }}
</main>
<footer>
{{ $footer }}
</footer>
</div>
</div>
</div>