Back to Top

How to create a time picker in Hyva || Hyva Timepicker

Updated 13 March 2024

Hello Readers !!

Today, I am going to drive you through the way of creating a custom time picker for Hyva-compatible Magento 2 extensions. Specifically, I created this time picker to make it compatible with the values provided by the Magento 2 default time picker widget. Without further wasting time let’s head over to the code!

Initialize the “timepicker” component by a div covering your input text field.

<div x-data="timepicker()">
    <div class="control">
        <input type="text"
         @click="showTimepicker = true;"
         x-model="timeSelected"
         name="start_time"
         id="start_time"
    </div>
    <!-- Add timepicker html here -->
</div>

Here is the time picker html which you have to add after the input field, though it has a good clean UI, you are free to make changes.

<div class="bg-white border-2 rounded-lg shadow p-4"
    @keydown.escape="closeTimePicker()"
    @click.away="closeTimePicker()"
    style="width: 17rem; position: absolute;"
    x-show.transition="showTimepicker">
    <div class="mb-4">
        <div class="flex flex-row justify-center items-center">
            <div class="flex flex-col items-center mx-2">
                <svg xmlns="http://www.w3.org/2000/svg"
                @click="increaseHour" fill="none"
                viewBox="0 0 24 24"
                stroke-width="1.5" stroke="currentColor"
                class="w-6 h-6 opacity-0 hover:opacity-100 
                transition-all duration-200 ease-[ease] 
                cursor-pointer">
                    <path stroke-linecap="round"
                        stroke-linejoin="round" 
                        d="M4.5 15.75l7.5-7.5 7.5 7.5" />
                </svg>
                <svg xmlns="http://www.w3.org/2000/svg"
                @click="decreaseHour" fill="none"
                viewBox="0 0 24 24"
                stroke-width="1.5" stroke="currentColor"
                class="w-6 h-6 opacity-0 hover:opacity-100 
                transition-all duration-200 ease-[ease] 
                cursor-pointer">
                    <path stroke-linecap="round"
                    stroke-linejoin="round"
                    d="M19.5 8.25l-7.5 7.5-7.5-7.5" />
                </svg>
            </div>
            <span x-text="hour.padStart(2, '0')"
            class="text-lg font-bold text-gray-800 mx-2"></span>
            <span class="mx-1 text-lg text-gray-600 font-bold mx-2">
                 <? =$escaper->escapeHtml(':')?></span>
            <span x-text="minute.padStart(2, '0')"
            class="text-lg font-bold text-gray-800 mx-2"></span>
            <div class="flex flex-col items-center mx-2">
                <svg xmlns="http://www.w3.org/2000/svg"
                @click="increaseMinute" fill="none"
                viewBox="0 0 24 24"
                stroke-width="1.5" stroke="currentColor"
                class="w-6 h-6 opacity-0 hover:opacity-100 
                transition-all duration-200 ease-[ease]
                cursor-pointer">
                    <path stroke-linecap="round"
                    stroke-linejoin="round"
                    d="M4.5 15.75l7.5-7.5 7.5 7.5" />
                </svg>
                <svg xmlns="http://www.w3.org/2000/svg"
                @click="decreaseMinute" fill="none"
                viewBox="0 0 24 24"
                stroke-width="1.5"
                stroke="currentColor"
                class="w-6 h-6 opacity-0 hover:opacity-100 
                transition-all duration-200 ease-[ease] 
                cursor-pointer">
                    <path stroke-linecap="round"
                    stroke-linejoin="round"
                    d="M19.5 8.25l-7.5 7.5-7.5-7.5" />
                </svg>
            </div>
        </div>
        <div class="flex flex-row justify-center item-center">
            <button @click.prevent="period = 'AM'; setTime();"
            class="bg-slate-200 hover:bg-slate-300 
            active:bg-slate-500 rounded 
            focus:outline-none focus:ring 
            focus:ring-slate-100 mr-2 p-1">
               <?=$escaper->escapeHtml('AM')?>
            </button>
            <button @click.prevent="period = 'PM'; setTime();"
            class="bg-slate-200 hover:bg-slate-300 
            active:bg-slate-500 rounded
            focus:outline-none focus:ring 
            focus:ring-slate-100 ml-2 p-1">
               <?=$escaper->escapeHtml('PM')?>
            </button>
        </div>
    </div>
    <div class="flex flex-row justify-between item-center px-4">
        <button @click.prevent="setCurrenTime"
        class="btn btn-secondary"><?=$escaper->escapeHtml('NOW')?></button>
        <button @click.prevent="closeTimePicker"
        class="btn btn-secondary"><?=$escaper->escapeHtml('OK')?></button>
    </div>
</div>

After adding the above HTML content you have to add this script to the page where you want to use the time picker, it is an Alpine Js component for time picker functionalities.

<script>
    function timepicker(format, timeString)
    {
        return {
            hour: "01",
            minute: "00",
            showTimepicker: false,
            period: "",
            format: "12h",
            timeSelected: "",
            init(){
                if(format == "12h" && timeString != ""){
                    let hour = Number(timeString.match(/^(\d+)/)[1]);
                    let minute = Number(timeString.match(/:(\d+)/)[1]);
                    let period = timeString.match(/\s(.*)$/)[1];
                    this.initTime(hour, minute, period, format);
                }
            },
            initTime(hour, minute, period, format){
                const now = new Date();
                this.hour = hour ?? now.getHours();
                this.minute = minute ?? now.getMinutes();
                this.period = period ?? this.period;
                this.format = format ?? this.format;
                let timeObj = this.formatTime(
                    this.format,
                    parseInt(this.hour),
                    parseInt(this.minute),
                    this.period
                );
                this.hour = timeObj?.hour.toString().padStart(2, '0');
                this.minute = timeObj?.minute.toString().padStart(2, '0');
                this.period = timeObj?.period.toString().padStart(2, '0');
                this.setTime();
            },
            setTime(timeObj){
                this.timeSelected = 
                `${this.hour.toString().padStart(2, '0')}:`+
                `${this.minute.toString().padStart(2, '0')}`+
                `${this.period}`;
            },
            setCurrenTime(){
                this.initTime(null, null, null, "12h");
            },
            increaseHour(){
                let hour = parseInt(this.hour);
                if(hour >= 12){
                    hour = 01;
                } else {
                    hour++;
                }
                this.hour = hour.toString();
            },
            decreaseHour(){
                let hour = parseInt(this.hour);
                if(hour <= 1){
                    hour = 12;
                } else {
                    hour--;
                }
                this.hour = hour.toString();
            },
            increaseMinute(){
                let minute = parseInt(this.minute);
                if(minute >= 59){
                    minute = 00;
                } else {
                    minute++;
                }
                this.minute = minute.toString();
            },
            decreaseMinute(){
                let minute = parseInt(this.minute);
                if(minute <= 0){
                    minute = 59;
                } else {
                    minute--;
                }
                this.minute = minute.toString();
            },
            formatTime(format, hour, min, period){
                hour = parseInt(hour);
                min = parseInt(min);
                if(format == "12h"){
                    if(hour >= 12){
                        hour = (hour % 12) || 12;
                        period = "PM";
                    }
                }
                if(format == "24h"){
                    if (period == "PM" && hour < 12) hour = hour + 12;
                    if (period == "AM" && hour == 12) hour = hour - 12;
                    period = "";
                }
                return 
                {hour: hour, minute: min, period: period, format: format};
            },
            closeTimePicker(){
                this.setTime();
                this.showTimepicker = false;
            }
        }
    }
</script>

Your time picker will look like this.

Start your headless eCommerce
now.
Find out More
timepicker

That’s it!

You are good to go for using this time picker and you can make modifications according to your needs.

Hope You Like it!

. . .

Leave a Comment

Your email address will not be published. Required fields are marked*


Be the first to comment.

Back to Top

Message Sent!

If you have more details or questions, you can reply to the received confirmation email.

Back to Home