Back to Course |
Practical Livewire 3: Order Management System Step-by-Step

Category Edit - Inline in the Table

Now we will make an editing form. But, differently from the Create form, this time we will make inline editing, so you could edit the category inside the table, without leaving the page.

edit category form

First, we need a public property to know which category will be edited.

app/Http/Livewire/CategoriesList.php:

class CategoriesList extends Component
{
// ...
 
public int $editedCategoryId = 0;
}

Next, we will add the wire:click action to the Edit button which will receive Category ID and in the component will be set to $editedCategoryId.

resources/livewire/categories-list.blade.php:

<x-primary-button>
<x-primary-button wire:click="editCategory({{ $category->id }})">
Edit
</x-primary-button>

app/Livewire/CategoriesList.php:

class CategoriesList extends Component
{
// ...
 
public function editCategory(int $categoryId): void
{
$this->editedCategoryId = $categoryId;
 
$this->category = Category::find($categoryId);
$this->name = $this->category->name;
$this->slug = $this->category->slug;
}
 
// ...
}

Now, for the form, when $editedCategoryId is set, we need to show the inputs, otherwise we show the values as text. For that, we will play with the CSS class hidden and some if-else statements.

resources/livewire/categories-list.blade.php:

//
<td class="px-6 py-4 text-sm leading-5 text-gray-900 whitespace-no-wrap">
{{ $category->name }}
</td>
<td class="px-6 py-4 text-sm leading-5 text-gray-900 whitespace-no-wrap">
{{ $category->slug }}
</td>
 
{{-- Inline Edit Start --}}
<td class="@if($editedCategoryId !== $category->id) hidden @endif px-6 py-4 text-sm leading-5 text-gray-900 whitespace-no-wrap">
<x-text-input wire:model.live.debounce="name" id="name" class="py-2 pr-4 pl-2 w-full text-sm rounded-lg border border-gray-400 sm:text-base focus:outline-none focus:border-blue-400" />
@error('name')
<span class="text-sm text-red-500">{{ $message }}</span>
@enderror
</td>
<td class="@if($editedCategoryId !== $category->id) hidden @endif px-6 py-4 text-sm leading-5 text-gray-900 whitespace-no-wrap">
<x-text-input wire:model="slug" id="slug" class="py-2 pr-4 pl-2 w-full text-sm rounded-lg border border-gray-400 sm:text-base focus:outline-none focus:border-blue-400" />
@error('slug')
<span class="text-sm text-red-500">{{ $message }}</span>
@enderror
</td>
{{-- Inline Edit End --}}
 
{{-- Show Category Name/Slug Start --}}
<td class="@if($editedCategoryId === $category->id) hidden @endif px-6 py-4 text-sm leading-5 text-gray-900 whitespace-no-wrap">
{{ $category->name }}
</td>
<td class="@if($editedCategoryId === $category->id) hidden @endif px-6 py-4 text-sm leading-5 text-gray-900 whitespace-no-wrap">
{{ $category->slug }}
</td>
{{-- Show Category Name/Slug End --}}
 
//

For buttons, it's very similar, when editing we need to show the Save and Cancel buttons, otherwise Edit and Delete.

resources/livewire/categories-list.blade.php:

@if($editedCategoryId === $category->id)
<x-primary-button wire:click="save">
Save
</x-primary-button>
<x-primary-button wire:click.prevent="cancelCategoryEdit">
Cancel
</x-primary-button>
@else
<x-primary-button wire:click="editCategory({{ $category->id }})">
Edit
</x-primary-button>
<button class="px-4 py-2 text-xs text-red-500 uppercase bg-red-200 rounded-md border border-transparent hover:text-red-700 hover:bg-red-300">
Delete
</button>
@endif

edit category form

As you can see, when saving, we use the same method save(). When creating a new category, we must check if the $category property is null. If it is null, then a new category will be created; otherwise updated.

When saving we need to check if $editedCategoryId is set, if it is we don't need to set position, and after saving reset $editedCategoryId.

For cancel, we add a new method cancelCategoryEdit() where we just need to reset $editedCategoryId and error bag.

app/Livewire/CategoriesList.php:

class CategoriesList extends Component
{
// ...
 
public function save()
{
$this->validate();
 
if (is_null($this->category)) {
$position = Category::max('position') + 1;
Category::create(array_merge($this->only('name', 'slug'), ['position' => $position]));
} else {
$this->category->update($this->only('name', 'slug'));
}
 
$this->reset('showModal');
$this->resetValidation();
$this->reset('showModal', 'editedCategoryId');
}
 
public function cancelCategoryEdit()
{
$this->resetValidation();
$this->reset('editedCategoryId');
}

After we click Save, the category data is updated both in the DB and in the table visually.

category after edit