Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

skoobi's avatar
Level 13

Date picker in component not updating on page

Hi. I'm pretty sure i'm missing something obvious, but cant see it at the moment. I have a date-picker component that I created which uses Pickaday, but when I select a date it doesn't update the Livewire component. Im pretty sure im missing some sort of emit.

Cheers

Here's the component in blade view:

<x-forms.date-picker-input model="start_date" label="Start Date"/>

Here's the component:

<div>

    <div x-data x-init="new Pikaday({ field: $refs.input, format: 'YYYY-MM-DD' })" class="w-full">

        <label for="{{ $model }}" class="block text-sm font-bold text-gray-700">
            {{ $label }} @if($required)
                <span class="text-red-600 font-sm">*</span>
            @endif
        </label>

        <div class="relative mt-1 rounded-md shadow-sm">
            <div class="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
                <svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5 text-gray-400" fill="none" viewBox="0 0 24 24"
                     stroke="currentColor" stroke-width="2">
                    <path stroke-linecap="round" stroke-linejoin="round"
                          d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"/>
                </svg>
            </div>
            <label>
                <input x-ref="input" type="text"
                       wire:model="{{ $model }}"
                       {{ $attributes->merge([
                       'class' =>
                           'pl-10 shadow-sm focus:ring-secondary focus:border-secondary block w-full sm:text-sm border-gray-300 rounded-md',
                       'type' => 'text',
                   ]) }}
                       placeholder="DD-MM-YYYY">
            </label>
        </div>
    </div>
</div>

In the livewire component i've tried to catch the updated hook to update the date and grab the data, but it doesn't hit that either:

public function updated(): void
    {
        dd("Hit");
        $this->projects = Project::query()
            ->whereHas('details', function (Builder $q) {
                $q->whereBetween('start', [$this->start_date, $this->end_date]);
            })
            ->with('details')
            ->get();

        $this->updateChart();
    }
0 likes
1 reply
LaryAI's avatar
LaryAI
AI
Best Answer
Level 58

It looks like the issue is that the Pikaday date picker is not directly integrated with Livewire's data binding. When you select a date using Pikaday, it updates the input field, but it doesn't notify Livewire of the change. To fix this, you need to manually emit an event to Livewire when the date is selected.

Here's how you can modify your component to emit a Livewire event when the date changes:

<div x-data x-init="
    new Pikaday({
        field: $refs.input,
        format: 'YYYY-MM-DD',
        onSelect: function() {
            $dispatch('input', this.getMoment().format('YYYY-MM-DD'))
        }
    })
" class="w-full">
    <!-- ... rest of your component -->
    <input x-ref="input" type="text"
           wire:model.lazy="{{ $model }}"
           {{ $attributes->merge([
               'class' => 'pl-10 shadow-sm focus:ring-secondary focus:border-secondary block w-full sm:text-sm border-gray-300 rounded-md',
               'type' => 'text',
           ]) }}
           placeholder="DD-MM-YYYY">
    <!-- ... rest of your component -->
</div>

In the x-init attribute, I've added an onSelect callback to the Pikaday configuration. This callback uses $dispatch to emit an input event with the selected date whenever a new date is picked. The wire:model.lazy directive is used to update the Livewire model only after the input event is dispatched, which should be when the user selects a date.

Make sure that your Livewire component is listening for the input event on the input element. If it's not, you can add an event listener like this:

protected $listeners = ['input' => 'updateDate'];

public function updateDate($value)
{
    $this->start_date = $value;
    $this->updated();
}

This will call the updateDate method on your Livewire component whenever the input event is dispatched, passing the selected date as $value. The updateDate method then updates the start_date property and calls the updated method to refresh the component with the new date.

Remember to test this solution and adjust it as necessary for your specific setup.

Please or to participate in this conversation.