Courses

Livewire 3 for Beginners with Laravel 12 Starter Kit

CRUD: Table of Tasks List

Summary of this lesson:
- Creating table layout with static data
- Passing real tasks from Livewire component
- Iterating tasks in Blade for display
- Adding pagination to task table

In the following lessons, we will fill our "Tasks" page with the full CRUD. Let's start with a table.


Table Component

Let's show the table of tasks. Remember, we had seeded it into the database previously:

Livewire starter kit uses a Livewire+Tailwind Flux so you don't need to install it, it comes already pre-configured.

Generally, using Flux components is very easy:

  1. Find component which you need.
  2. Call it as a Blade component.

Unfortunately, Flux isn't completely free; some components are available only as Pro components. Luckily, we can use anything else. In this case, I chose a table component from Flowbite.

You can extract different table parts into Blade components. For simplicity, I will use plain HTML table code.

resources/views/tasks/index.blade.php:

<section>
<div class="relative overflow-x-auto shadow-md sm:rounded-lg">
<table class="w-full text-sm text-left rtl:text-right text-gray-500 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">
Task
</th>
<th scope="col" class="px-6 py-3">
Status
</th>
<th scope="col" class="px-6 py-3">
Actions
</th>
</tr>
</thead>
<tbody>
<tr class="odd:bg-white odd:dark:bg-gray-900 even:bg-gray-50 even:dark:bg-gray-800 border-b dark:border-gray-700 border-gray-200">
<th scope="row" class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap dark:text-white">
Task name will be here
</th>
<td class="px-6 py-4">
Completed or in progress
</td>
<td class="px-6 py-4 space-x-2">
<flux:button href="#" variant="filled">{{ __('Edit') }}</flux:button>
<flux:button variant="danger" type="button">{{ __('Delete') }}</flux:button>
</td>
</tr>
</tbody>
</table>
</div>
</section>

As you can see, for the action buttons, we use components from the Flux.


Real Tasks in the Table

First, we need to pass tasks to the View.

app/Livewire/Tasks/Index.php:

use App\Models\Task;
use Livewire\Component;
use Illuminate\View\View;
 
class Index extends Component
{
public function render(): View
{
return view('livewire.tasks.index');
return view('livewire.tasks.index', [
'tasks' => Task::all(),
]);
}
}

Now, in the table we can iterate tasks and show them.

resources/views/livewire/tasks/index.blade.php

BEFORE:

<tbody>
<tr class="odd:bg-white odd:dark:bg-gray-900 even:bg-gray-50 even:dark:bg-gray-800 border-b dark:border-gray-700 border-gray-200">
<th scope="row" class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap dark:text-white">
Task name will be here
</th>
<td class="px-6 py-4">
Completed or in progress
</td>
<td class="px-6 py-4 space-x-2">
<flux:button href="#" variant="filled">{{ __('Edit') }}</flux:button>
<flux:button variant="danger" type="button">{{ __('Delete') }}</flux:button>
</td>
</tr>
</tbody>

AFTER:

<tbody>
@foreach($tasks as $task)
<tr class="odd:bg-white odd:dark:bg-gray-900 even:bg-gray-50 even:dark:bg-gray-800 border-b dark:border-gray-700 border-gray-200">
<th scope="row" class="px-6 py-4 font-medium text-gray-900 whitespace-nowrap dark:text-white">
{{ $task->name }}
</th>
<td class="px-6 py-4">
<span @class([
'text-green-600' => $task->is_completed,
'text-red-700' => ! $task->is_completed,
])>
{{ $task->is_completed ? 'Completed' : 'In progress' }}
</span>
</td>
<td class="px-6 py-4 space-x-2">
<flux:button href="#" variant="filled">{{ __('Edit') }}</flux:button>
<flux:button variant="danger" type="button">{{ __('Delete') }}</flux:button>
</td>
</tr>
@endforeach
</tbody>

And here's the visual result:


Pagination

To add a pagination you must add the WithPagination trait to the Livewire component. Then on the query you can paginate data.

app/Livewire/Index/Tasks.php:

use Livewire\WithPagination;
 
class Index extends Component
{
use WithPagination;
 
public function render(): View
{
return view('livewire.tasks.index', [
'tasks' => Task::all(),
'tasks' => Task::paginate(3),
]);
}
}

In the Blade file, now we can show the links.

resources/views/livewire/tasks/index.blade.php:

<section>
// ...
 
@if($tasks->hasPages())
<div class="mt-5">
{{ $tasks->links() }}
</div>
@endif
</section>

Great, we have our table with data.

In the following lessons, we'll take care of the Delete action.


The repository for this starter kit project section is here on GitHub.

No comments yet…

avatar
You can use Markdown