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

Categories Table - Toggle Active

You probably have noticed that we have "Active" toggle in the table. Let's implement its behavior, so you could click on that Toggle to change the value immediately, without leaving the table page.

This is the expected result, visually:

Better toggle button

You might have seen that in Categories migration we have a column is_active, so we will change its value in the database.

First, we need a public property in the Livewire Component. It will be an array and called $active.

app/Livewire/CategoriesList.php:

class CategoriesList extends Component
{
use WithPagination;
 
public Category $category;
 
public bool $showModal = false;
 
public array $active = [];
//
}

Next, we need a list of active categories. For this, we will use a Collections method mapWithKeys().

class CategoriesList extends Component
{
//
public function render(): View
{
$categories = Category::paginate(10);
 
$this->active = $categories->mapWithKeys(
fn (Category $item) => [$item['id'] => (bool) $item['is_active']]
)->toArray();
 
return view('livewire.categories-list', [
'categories' => $categories,
]);
}
//
}

This will return the array result of category_id => true/false:

array:10 [▼ // app/Http/Livewire/CategoriesList.php:50
1 => true
2 => true
3 => true
4 => true
5 => true
6 => true
7 => true
8 => true
9 => true
10 => true
]

Now we can bind the toggle button to the active property and add action to the toggle activity, with this code:

wire:model="active.{{ $category->id }}"
wire:click="toggleIsActive({{ $category->id }})"

The full code of the <td> column:

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

<td class="px-6">
<div class="inline-block relative mr-2 w-10 align-middle transition duration-200 ease-in select-none">
<input type="checkbox" name="toggle" class="block absolute w-6 h-6 bg-white rounded-full border-4 appearance-none cursor-pointer focus:outline-none toggle-checkbox" />
<label for="toggle" class="block overflow-hidden h-6 bg-gray-300 rounded-full cursor-pointer toggle-label"></label>
<input wire:model="active.{{ $category->id }}" wire:click="toggleIsActive({{ $category->id }})" type="checkbox" name="toggle" id="{{ $loop->index.$category->id }}" class="block absolute w-6 h-6 bg-white rounded-full border-4 appearance-none cursor-pointer focus:outline-none toggle-checkbox" />
<label for="{{ $loop->index.$category->id }}" class="block overflow-hidden h-6 bg-gray-300 rounded-full cursor-pointer toggle-label"></label>
</div>
</td>

By default, all categories are active, so you should see all of them marked as active in the table:

active categories

To make a button look like a toggle button, we need to add some custom CSS.

resources/css/app.css:

@tailwind base;
@tailwind components;
@tailwind utilities;
 
.toggle-checkbox:checked {
@apply right-0 border-green-400;
}
 
.toggle-checkbox:checked + .toggle-label {
@apply bg-green-400;
}

Better toggle button

Next, we will make the button work. In the Blade file, we called the action toggleIsActive which receives category ID.

app/Livewire/CategoriesList.php:

class CategoriesList extends Component
{
// ...
 
public function toggleIsActive(int $categoryId): void
{
Category::where('id', $categoryId)->update([
'is_active' => $this->active[$categoryId],
]);
}
 
// ...

This method is very simple, we just need to update Category with the value from the $active property, calling the specific element.

That's it, our active/inactive Toggle button works!