mymth / vanillajs-datepicker

A vanilla JavaScript remake of bootstrap-datepicker for Bulma and other CSS frameworks
MIT License
719 stars 147 forks source link

vanillajs-datepicker does not set input value, no change event triggered #184

Closed raliqala closed 2 months ago

raliqala commented 2 months ago

Good day

I'm using this datepicker and I like it but its not triggering the change event on an input after I click a date.

Here is my code
I tested this on jsFiddle

<input type="text" name="foo">

const elem = document.querySelector('input[name="foo"]');
const datepicker = new Datepicker(elem, {
  autohide: true,
  todayHighlight: true,
  format: "yyyy-mm-dd",
});

elem.addEventListener("change", function (e) {
  console.log(e.target.value);
});

When I click the specific date on the datepicker the change event is not triggered.

I need help with this.

I'm also using it with livewire and alpine but after clicking the date the change even is not triggered. here is my laravel code
code

How can I fix this or make it to trigger the change even.

Thanks in advance.

raliqala commented 2 months ago

This is the working component for vanillajs datepicker, I got help for the event listener from chris-g in this stackoverflow question

@php
    $date = new \DateTime('1900-01-01');
    $date_set = $date->format(DateTime::W3C);
@endphp

@props([
    'id' => 'datepicker',
    'label' => 'Date',
    'placeholder' => '',
    'minDate' => $date_set,
    'className' => '',
    'requreLabel' => 'false',
])

<div>
    @if ($requreLabel == 'true')
        <label for="Exp"
            class="block mb-2 text-sm font-medium text-gray-900 dark:text-white {{ $className }}">{{ $label }}</label>
    @endif

    <div wire:ignore x-data="datepicker(@entangle($attributes->wire('model')))" class="relative w-full">
        <div class="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
            <svg class="w-4 h-4 text-gray-500 dark:text-gray-400" aria-hidden="true" xmlns="http://www.w3.org/2000/svg"
                fill="currentColor" viewBox="0 0 20 20">
                <path
                    d="M20 4a2 2 0 0 0-2-2h-2V1a1 1 0 0 0-2 0v1h-3V1a1 1 0 0 0-2 0v1H6V1a1 1 0 0 0-2 0v1H2a2 2 0 0 0-2 2v2h20V4ZM0 18a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V8H0v10Zm5-8h10a1 1 0 0 1 0 2H5a1 1 0 0 1 0-2Z" />
            </svg>
        </div>
        <input x-ref="{{ $id }}" x-model="value" type="text"
            class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full pl-10 p-2.5  dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
            placeholder="{{ $placeholder }}">
    </div>
</div>

@once
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vanillajs-datepicker@1.3.4/dist/css/datepicker.min.css">
    <script
        src="https://cdn.jsdelivr.net/npm/vanillajs-datepicker@1.3.4/dist/js/datepicker-full.min.js?id=<?= rand(0, 1000 - 1) ?>"
        data-navigate-track></script>

    <script>
        document.addEventListener('alpine:init', () => {
            Alpine.data('datepicker', (model) => ({
                value: model,
                init() {
                    this.pickr = new Datepicker(this.$refs.{{ $id }}, {
                        autohide: true,
                        todayHighlight: true,
                        format: "yyyy-mm-dd",
                        minDate: '<?= $minDate ?>',
                        nextArrow: '<svg class="w-4 h-4 rtl:rotate-180 text-gray-800 dark:text-white ml-1" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 10"><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M1 5h12m0 0L9 1m4 4L9 9"/></svg>',
                        prevArrow: '<svg class="w-4 h-4 rtl:rotate-180 text-gray-800 dark:text-white ml-1" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 10"><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 5H1m0 0 4 4M1 5l4-4"/></svg>',
                        buttonClass: 'text-sm rounded-lg text-gray-900 dark:text-white bg-white dark:bg-gray-700 font-semibold py-2.5 px-5 hover:bg-gray-100 dark:hover:bg-gray-600 focus:outline-none focus:ring-2 focus:ring-gray-200',
                    })

                    this.$refs.{{ $id }}.addEventListener("changeDate", (e) => {
                        this.$refs.{{ $id }}.value = e.target.value;
                        this.$refs.{{ $id }}.dispatchEvent(new Event('input', { 'bubbles': true }));
                    });

                    this.$watch('value', function(newValue) {
                        this.pickr.setDate(newValue);
                    }.bind(this));
                }
            }))
        })
    </script>
@endonce