Courses

Livewire 3 for Beginners with Laravel 12 Starter Kit

Date Picker with due_date Field

Summary of this lesson:
- Adding a `due_date` field to the database and model
- Implementing validation and saving/updating the `due_date` in the Livewire component
- Adding a date input field in the form using the native browser date picker
- Displaying the `due_date` in the tasks table with formatted output

Now, let's try to add one more field to our form and database: due_date with a date picker.


Prepare Database/Livewire Component

I will just show you the code without any comments. These are Laravel fundamentals, I'm sure you know them.

Migration:

php artisan make:migration add_due_date_to_tasks_table
Schema::table('tasks', function (Blueprint $table) {
$table->date('due_date')->nullable();
});

Then, we run:

php artisan migrate

Adding to Model fillables:

app/Models/Task.php:

class Task extends Model
{
use HasFactory;
 
protected $fillable = [
'name',
'is_completed',
'due_date',
];
 
protected function casts(): array
{
return [
'is_completed' => 'boolean',
'due_date' => 'date'
];
}
}

Validation rules and saving/updating date:

app/Livewire/Tasks/Create.php:

class Create extends Component
{
#[Validate('required|string|max:255')]
public string $name = '';
 
#[Validate('nullable|date')]
public null|string $due_date = null;
 
public function save(): void
{
$this->validate();
 
Task::create([
'name' => $this->name,
'due_date' => $this->due_date,
]);
 
session()->flash('success', 'Task successfully created.');
 
$this->redirectRoute('tasks.index', navigate: true);
}
 
// ...
}

app/Livewire/Tasks/Edit.php:

class Edit extends Component
{
#[Validate('required|string|max:255')]
public string $name;
 
#[Validate('nullable|boolean')]
public bool $is_completed;
 
#[Validate('nullable|date')]
public null|string $due_date = null;
 
public Task $task;
 
public function mount(Task $task): void
{
$this->task = $task;
$this->name = $task->name;
$this->is_completed = $task->is_completed;
$this->due_date = $task->due_date?->format('Y-m-d');
}
 
public function save(): void
{
$this->validate();
 
$this->task->update([
'name' => $this->name,
'is_completed' => $this->is_completed,
'due_date' => $this->due_date,
]);
 
session()->flash('success', 'Task successfully updated.');
 
$this->redirectRoute('tasks.index', navigate: true);
}
 
// ...
}

Ok, the back end is ready. It's time to dive into the Blade side.


Adding the Input Date to the Form

We cannot use Flux date picker component as it is for Pro version. But, in this case, native browser date input type is enough.

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

<section class="max-w-5xl">
<form wire:submit="save" class="flex flex-col gap-6">
<flux:input
wire:model="name"
:label="__('Task Name')"
required
badge="required"
/>
 
<flux:input
wire:model="due_date"
type="date"
:label="__('Due Date')"
/>
 
<div>
<flux:button variant="primary" type="submit">{{ __('Save') }}</flux:button>
</div>
</form>
</section>

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

<section class="max-w-5xl">
<form wire:submit="save" class="flex flex-col gap-6">
<flux:input
wire:model="name"
:label="__('Task Name')"
required
badge="required"
/>
 
<flux:switch
wire:model="is_completed"
label="Completed?"
align="left"
/>
 
<flux:input
wire:model="due_date"
type="date"
:label="__('Due Date')"
/>
 
<div>
<flux:button variant="primary" type="submit">{{ __('Save') }}</flux:button>
</div>
</form>
</section>

Here's the visual result:

And if we submit the form, the due_date is successfully saved into the DB:


Show Date in the Table

This one is easy. Just add a few lines in the tasks/index.blade.php.

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

// ...
 
<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">
Due date
</th>
<th scope="col" class="px-6 py-3">
Actions
</th>
</tr>
</thead>
<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">
{{ $task->due_date?->format('M d, Y') }}
</td>
<td class="px-6 py-4 space-x-2">
<flux:button href="{{ route('tasks.edit', $task) }}" variant="filled">{{ __('Edit') }}</flux:button>
<flux:button wire:confirm="Are you sure?" wire:click="delete({{ $task->id }})" variant="danger" type="button">{{ __('Delete') }}</flux:button>
</td>
</tr>
@endforeach
</tbody>
</table>
 
// ...

And here's the visual result:


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

Previous: CRUD: Edit Task Form

No comments yet…

avatar
You can use Markdown