Skip to main content

Due Date: Can't Use Shadcn Date Picker

Premium
5 min read

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


Prepare Database/Controller

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:

app/Http/Requests/StoreTaskRequest.php:

// ...
public function rules(): array
{
return [
'name' => ['required', 'string', 'max:255'],
'due_date' => ['nullable', 'date'],
];
}

app/Http/Requests/UpdateTaskRequest.php:

public function rules(): array
{
return [
'name' => ['required', 'string', 'max:255'],
'is_completed' => ['required', 'boolean'],
'due_date' => ['nullable', 'date'],
];
}

No modifications are needed for the Controller since we use $request->validated() to create/update tasks.

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


Adding Field to TypeScript Types

We need to update our type in the file of all types:

resources/js/types/index.d.ts

export interface Task {
id: number;
name: string;
is_completed: boolean;
due_date?: string;
created_at: string;
updated_at: string;
}

Also, in our Create.tsx page, we need to...

The Full Lesson is Only for Premium Members

Want to access all of our courses? (36 h 00 min)

You also get:

60 courses
Premium tutorials
Access to repositories
Private Discord
Get Premium for $129/year or $29/month

Already a member? Login here

Richard A. Hoyle avatar

How hard would it be to set the calende picker with the date and time aswell ?

Povilas Korop avatar

If we go for native browser, maybe input type="datetime-local"?

Luis Antonio Parrado avatar
Luis Antonio Parrado

I had problems with the date-fns library, incorrect format in the picker, I used dayjs instead.

Richard A. Hoyle avatar

Can you show us what you changed to get this to work? I added the npm install dayjs –save But what else do I have to do to get this to work?

Steve Popoola avatar

date-fns worked for me without any problems.

npm install date-fns --save

In Create.tsx

import { format } from 'date-fns';

Use the format function

<Input
id="due_date"
value={data.due_date}
onChange={(e) => setData('due_date', format(new Date(e.target.value), 'yyyy-MM-dd'))}
className="mt-1 block w-full"
type="date"
/>

What problems were you having?

Steve Popoola avatar

Hi Povilas,

Something minor but important: In Create.tsx, the form is defined in the article as;

interface CreateTaskForm {
name?: string,
due_date?: string
}

But it was actually created earlier as type and should be:

type CreateTaskForm = {
name?: string;
due_date?: string;
}

The same with EditTaskForm:

type EditTaskForm = {
name: string;
is_completed: boolean;
due_date?: string;
};
Modestas avatar

Hi, thanks for letting us know! I've updated the lesson to fix this :)

ps. This was a left-over update from following starter kit changes https://github.com/laravel/react-starter-kit/commit/bb97832a09926ab9c28b6bde87262fca4bc1800a#diff-6dcdf3ad723e9f82263160236fdb941e99915e8171a4f807b8a95a5c2aa89841R13

Steve Popoola avatar

Under "Adding the Input Date to the Form" (For Create) , the following is missing:

const { data, setData, errors, post, reset, processing } = useForm<Required<CreateTaskForm>>({
name: '',
due_date: format(new Date(), 'yyyy-MM-dd'), // This needs to be added
});
Modestas avatar

This would set the due_date to today, but we intentionally left it null as we don't want to fill it with any default value.

Or was there any other reason for this?

Steve Popoola avatar

I meant the due_date property is missing which throws an error

Modestas avatar

But it is there, no?

type CreateTaskForm {
name?: string,
due_date?: string
}
 
export default function Create() {
// ...
 
const { data, setData, errors, post, reset, processing } = useForm<Required<CreateTaskForm>>({
name: '',
due_date: '',
});
}

This is taken from the lesson and seems to be exactly what you are referring to

Steve Popoola avatar

Ah! seen that it was previously set before that secton. No worries!

Steve Popoola avatar

While the Edit form works with the addition of due_date, TypeScript is complaining, "Type 'string | undefined' is not assignable to type 'string'. Type 'undefined' is not assignable to type 'string'." I believe this is because we have defined due_date as optional in the type but by wrapping EditTaskForm with Required, we are making all the properties of EditTaskForm required.

I was able to fix the TypeScript error by making due_date optional as follows:

type EditTaskForm = {
name: string;
is_completed: boolean;
due_date: string | null;
};

I removed the Required from useForm and passed due_date or null

const { data, setData, errors, put, reset, processing } = useForm<EditTaskForm>({
name: task.name,
is_completed: task.is_completed,
due_date: task.due_date || null,
});
👍 3
melwyn.turbant avatar

As of today, Shadcn date picker can now easily be used here.

We'd Love Your Feedback

Tell us what you like or what we can improve

Feel free to share anything you like or dislike about this page or the platform in general.