1/** 2 * TimePicker - Classe per la selezione dell'orario 3 * 4 * Genera opzioni ogni 30 minuti (00:00, 00:30, ..., 23:30). 5 * Utilizza l'oggetto globale LANG per le traduzioni. 6 * 7 * @example 8 * const timePicker = new TimePicker('time-pickup-group', 'time-pickup-display', 'time-pickup-dropdown', '10:00'); 9 */ 10class TimePicker { 11 /** 12 * @param {string} groupId - ID del container del time picker 13 * @param {string} displayId - ID dell'elemento che mostra l'ora selezionata 14 * @param {string} dropdownId - ID del dropdown con le opzioni 15 * @param {string} defaultTime - Ora di default (formato HH:MM) 16 */ 17 constructor(groupId, displayId, dropdownId, defaultTime = '10:00') { 18 this.group = document.getElementById(groupId); 19 this.display = document.getElementById(displayId); 20 this.dropdown = document.getElementById(dropdownId); 21 this.selectedTime = defaultTime; 22 23 this.generateOptions(); 24 this.initEvents(); 25 this.display.textContent = defaultTime; 26 } 27 28 // ============================================ 29 // INITIALIZATION 30 // ============================================ 31 32 /** 33 * Genera le opzioni orario ogni 30 minuti 34 */ 35 generateOptions() { 36 this.dropdown.innerHTML = ''; 37 38 for (let h = 0; h < 24; h++) { 39 for (let m = 0; m < 60; m += 30) { 40 const hour = h.toString().padStart(2, '0'); 41 const min = m.toString().padStart(2, '0'); 42 const time = `${hour}:${min}`; 43 44 const option = document.createElement('button'); 45 option.type = 'button'; 46 option.className = 'time-option'; 47 option.textContent = time; 48 option.dataset.time = time; 49 50 if (time === this.selectedTime) { 51 option.classList.add('selected'); 52 } 53 54 option.addEventListener('click', (e) => { 55 e.stopPropagation(); 56 this.selectTime(time); 57 }); 58 59 this.dropdown.appendChild(option); 60 } 61 } 62 } 63 64 /** 65 * Inizializza gli event listeners 66 */ 67 initEvents() { 68 this.group.addEventListener('click', (e) => { 69 e.stopPropagation(); 70 this.toggle(); 71 }); 72 } 73 74 // ============================================ 75 // PUBLIC METHODS 76 // ============================================ 77 78 /** 79 * Apre/chiude il dropdown 80 */ 81 toggle() { 82 const isOpen = this.dropdown.classList.contains('show'); 83 84 // Chiudi tutti gli altri dropdown 85 document.querySelectorAll('.time-dropdown.show').forEach(d => d.classList.remove('show')); 86 document.querySelectorAll('.time-picker-group.open').forEach(g => g.classList.remove('open')); 87 88 if (!isOpen) { 89 this.dropdown.classList.add('show'); 90 this.group.classList.add('open'); 91 92 // Scroll all'opzione selezionata 93 const selected = this.dropdown.querySelector('.selected'); 94 if (selected) { 95 setTimeout(() => { 96 selected.scrollIntoView({ block: 'center' }); 97 }, 50); 98 } 99 100 // Mostra overlay e attiva z-index 101 const overlay = document.getElementById('focus-overlay'); 102 const searchCard = document.getElementById('main-search-card'); 103 104 if (overlay) overlay.classList.add('active'); 105 if (searchCard) searchCard.classList.add('allow-popout'); 106 107 this.group.classList.add('z-active'); 108 } 109 } 110 111 /** 112 * Seleziona un orario 113 * @param {string} time - Orario nel formato HH:MM 114 */ 115 selectTime(time) { 116 this.selectedTime = time; 117 this.display.textContent = time; 118 119 // Aggiorna stato selected 120 this.dropdown.querySelectorAll('.time-option').forEach(opt => { 121 opt.classList.toggle('selected', opt.dataset.time === time); 122 }); 123 124 this.close(); 125 } 126 127 /** 128 * Chiude il dropdown e rimuove overlay/z-active 129 */ 130 close() { 131 this.dropdown.classList.remove('show'); 132 this.group.classList.remove('open'); 133 134 // Chiudi overlay e rimuovi z-active
135 var overlay = document.getElementById('focus-overlay'); 136 var searchCard = document.getElementById('main-search-card'); 137 if (overlay) overlay.classList.remove('active'); 138 if (searchCard) searchCard.classList.remove('allow-popout'); 139 document.querySelectorAll('.input-group').forEach(function(el) { 140 el.classList.remove('z-active'); 141 }); 142 } 143 144 /** 145 * Ritorna l'orario selezionato 146 * @returns {string} Orario nel formato HH:MM 147 */ 148 getValue() { 149 return this.selectedTime; 150 } 151 152 /** 153 * Imposta l'orario selezionato 154 * @param {string} time - Orario nel formato HH:MM 155 */ 156 setValue(time) { 157 this.selectTime(time); 158 } 159}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.