Search code examples
javascriptalpine.jssession-storagepersistflatpickr

Flatpickr AlpineJS Persist Plugin on Dange Range Selection


I have a perfectly working Flatpickr Date Range calendar that stores the dates in session storage. Here is my code:

<div
    x-data="{
        chosenDates: sessionStorage.getItem('_x_range'),
        value: [],
        init() {
            let picker = flatpickr(this.$refs.picker, {
                mode: 'range',
                inline: false,
                dateFormat: 'm/d/Y',
                showMonths: 2,

            })

            this.$watch('value', () => picker.setDate(this.value))
        },
    }"
>
    <div class="flex items-center flex-1 gap-2 overflow-hidden border border-gray-500 rounded-lg">
        <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="ml-4 bi bi-calendar-event-fill" viewBox="0 0 16 16">
            <path d="M4 .5a.5.5 0 0 0-1 0V1H2a2 2 0 0 0-2 2v1h16V3a2 2 0 0 0-2-2h-1V.5a.5.5 0 0 0-1 0V1H4zM16 14V5H0v9a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2m-3.5-7h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5v-1a.5.5 0 0 1 .5-.5"/>
        </svg>
        <input id="rangeValue" :value="chosenDates" placeholder="Add dates"   x-ref="picker" type="text" class="p-0 py-4 placeholder-gray-600 border-0 bg-none focus:ring-0 " data-input>
    </div>
</div>

Set item:

function dateRange() {
    var date = document.getElementById("rangeValue").value;
    sessionStorage.setItem("_x_range", date);
    sessionStorage.setItem("start", start);
    sessionStorage.setItem("end", end);
    const start = sessionStorage.getItem("start");
}
$('#rangeValue').on('focus', ({ currentTarget }) => $(currentTarget).blur())
$("#rangeValue").prop('readonly', false)

Receive item:

if (sessionStorage.getItem("_x_range") != null) {
    document.getElementById("chosenRange").innerHTML = sessionStorage.getItem("_x_range");
    document.getElementById("rangeValue").value = sessionStorage.getItem("_x_range");
}

If possible, I would like to learn how to set this up using AplineJS and Persist instead, in order to not overdue it with too much code.

Is it even possible?


Solution

  • This is a possible solution:

    <div x-data="{
                        thePicker: null,
    
                        chosenDates: $persist([]).using(sessionStorage).as('_x_range'),
    
                        init() {
                            this.thePicker = flatpickr(this.$refs.picker, {
                                mode: 'range',
                                inline: false,
                                dateFormat: 'm/d/Y',
                                showMonths: 2,
                                defaultDate: this.chosenDates,
                                onChange: (selectedDates) => {this.chosenDates = [...selectedDates];}
                            });
                        },
                    }"
    >
    
        <div class="flex items-center flex-1 gap-2 overflow-hidden border border-gray-500 rounded-lg">
    
            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="ml-4 bi bi-calendar-event-fill" viewBox="0 0 16 16">
                <path d="M4 .5a.5.5 0 0 0-1 0V1H2a2 2 0 0 0-2 2v1h16V3a2 2 0 0 0-2-2h-1V.5a.5.5 0 0 0-1 0V1H4zM16 14V5H0v9a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2m-3.5-7h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5v-1a.5.5 0 0 1 .5-.5"/>
            </svg>
    
            <input type="text"
                   x-ref="picker"
                   placeholder="Add dates"
                   class="p-0 py-4 placeholder-gray-600 border-0 bg-none focus:ring-0"
            >
    
            <span title="Clear"
                  class="text-blue-600 cursor-pointer"
                  @click="thePicker.clear()"
            >
                X
            </span>
    
        </div>
    
        <div x-text="chosenDates"> </div>
    
    </div>
    
    

    The date range is stored in the Alpine chosenDates variable, which is persisted via Persist and initialized to an empty array.
    When the datepicker is initialized, the chosenDates variable is used to fill the defaultDate parameter.
    When a date range is selected, flatpicker fires the onChage event, so I used that to copy the new range into the chosenDates variable.
    I added a "clear" button to reset the input field in the flatpicker way, calling the clear() method (it's a simple example), then I had to store the flatpicker reference in thePicker variable .
    I also added a <div> to show the contents of choosenDates via x-text

    No other Javascript is needed.