Following this question and this other question, I managed to create the flatpickr element and to send data to the backend. The problem is that, although in the Rule that validates the datetime the passes method returns false, the validation error is not shown in the form.
For sake of easy-reading, this is the blade portion for the datepicker:
<div class="mb-3" wire:ignore>
<label for="pickeddatetime" class="form-label">Date and time</label>
<input id="pickeddatetime" class="form-control @error('pickeddatetime') is-invalid @enderror"
type="datetime-local" name="pickeddatetime" placeholder="Pick a date and time"
value="{{ old('pickeddatetime') }}" wire:model.debounce.500ms="pickeddatetime">
@error('pickeddatetime')
<p class="invalid-feedback">{{ $errors->first('pickeddatetime') }}</p>
@enderror
</div>
I believe it is due to the wire:ignore directive (used to make flatpickr work with Livewire) preventing any change in the DOM but, again, I'm still learning and thus be completely wrong.
Update
I moved wire:ignore inside the input field, and that's the only change I made in the Blade file. There are no other wire:ignore in there, and the @livewireScripts is in the layout file (I can see the scripts in the DOM of the Livewire component).
The validation goes as follows: when the datetime is selected, the updatedPickeddatetime is called (and indeed it is)
public function updatedPickeddatetime($value)
{
$rules = $this->rules();
$rules['pickeddatetime'][] = new TimeSlotEmployeeRule($this->employee_id);
$this->validateOnly('pickeddatetime', $rules);
}
In the TimeSlotEmployeeRule the passes method returns false (for testing purposes).
I placed some strategic dds inside the validateOnly method, and i can see that the ValidationException is thrown and the ErrorBag contains the expected message.
Yet, the @error directive (for the p element) isn't triggered and the element is not shown.
Update 2: solved!
Apparently, the problem was related, but laying somewhere else: the @error directive works fine, but I noticed that in the DOM the p was set as display:none. This, I think, is related to the fact that the input doesn't get its is-invalid class, and thus the invalid-feedback gets hidden.
I therefore changed it to <p class="invalid-feedback d-block"> (as suggested here) and it works!