[Live Component] Datepicker bug at onchange
I have a date type input, the goal is that when I choose a date in the datepicker, a live-action is executed, but my live action is executed even though I have not finished choosing my date, as soon as I click on a month in the datepicker, the live-action executes, the same when I click on the arrows.
Native HTML date inputs are tricky and buggy. Even MDN suggest to not use them.
At the moment, the best way to deal with dates in forms in a cross-browser way is to have the user enter the day, month, and year in separate controls, or to use a JavaScript library such as jQuery date picker.
Maybe try to use a JS datepicker like https://github.com/adrienpoly/stimulus-flatpickr
Something like this works great for me:
// assets/controllers/flatpickr_controller.ts
// @ts-nocheck
import Flatpickr from 'stimulus-flatpickr'
import 'flatpickr/dist/themes/light.css'
export default class extends Flatpickr {
config = {}
initialize() {
this.config = {
time_24hr: true,
weekNumbers: true,
};
}
}
<input
class="w-28"
type="text"
autofocus
data-model="on(change)|target"
value="{{ target|date('Y-m-d') }}"
data-controller="flatpickr"
data-flatpickr-date-format="Y-m-d" {# <--- note there is no '-value' at the end here #}
/>
There may be something to improve on our side concerning events (input / change / etc).
(That concern colorpicker, datepicker.... and every UI element with potential multiple steps)
Good morning, Thank you for your answers, I tried flatpickr stimulus, it works really well. Thank you so much ! @1ed
Do you plan to see how to resolve the date problem? @smnandre
Honestly there is almost no chance i'll have time on this direct subject in the next weeks (months?)
Couple of things in mind:
- datetime-local inputs feel easier to use / less buggy
- you could implement yourself a layer between your input and your action. Use a intermeriardy action that listen the value to really have changed (or listen to input & change on the input) and trigger an event only when on "blur" (and other two, but you see the idea)
I'm also thinking every day more and more that i'd like to make a full PHP/CSS live-calendar ... that could be used as datepicker too..
and it's a lot less useless/stupid that is sounds.
I have stumbled upon this problem a while ago and this is my solution:
class foo
{
#[LiveProp(writable: true, format: 'Y-m-d')]
public ?\DateTimeImmutable $date = null;
#[LiveProp(writable: true, onUpdated: 'updateDate')]
public ?string $dateChooser = null;
public function updateDate(): void
{
try {
$date = \DateTimeImmutable::createFromFormat('Y-m-d', $this->dateChooser);
if ($date) {
$this->date = $date;
}
} catch (\Exception) {
// Don't update on incorrect date
}
}
}
With this code I bind dateChooser in place of date on <input type="date" /> and it seems to work flawlessly.