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.
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!
Be the first to comment.