1function initDatePicker(debug) { 2 const startDateInput = document.querySelector("#startDate"); 3 const endDateInput = document.querySelector("#endDate"); 4 if (!startDateInput) return; 5 6 const toISO = (d) => { 7 const z = new Date(Date.UTC(d.getFullYear(), d.getMonth(), d.getDate())); 8 return z.toISOString().split("T")[0]; 9 }; 10 const atMidnight = (x) => { 11 if (typeof x === 'string') { 12 const [yy, mm, dd] = x.split('-').map(Number); 13 return new Date(yy, mm - 1, dd, 0, 0, 0, 0); 14 } 15 return new Date(x.getFullYear(), x.getMonth(), x.getDate()); 16 }; 17 18 const today = atMidnight(new Date()); 19 const bufferDays = parseInt(startDateInput.dataset.bufferDays, 10) || 0; 20 const bufferedMinDate = new Date(today); 21 bufferedMinDate.setDate(bufferedMinDate.getDate() + bufferDays); 22 23 const configuredMinDate = startDateInput.dataset.minDate 24 ? atMidnight(startDateInput.dataset.minDate) 25 : null; 26 const minDate = configuredMinDate && configuredMinDate > bufferedMinDate 27 ? configuredMinDate 28 : bufferedMinDate; 29 30 const maxFutureDate = atMidnight(new Date()); 31 maxFutureDate.setFullYear(maxFutureDate.getFullYear() + 1); 32 maxFutureDate.setMonth(maxFutureDate.getMonth() + 6); 33 34 const initialMax = startDateInput.dataset.maxDate 35 ? atMidnight(startDateInput.dataset.maxDate) 36 : maxFutureDate; 37 38 const maxSpan = parseInt(startDateInput.dataset.maxSpan, 10) || 90; 39 const isPauschDetail = !!document.querySelector(".pausch-detail"); 40 41 const getCurrentDuration = () => { 42 const checked = document.querySelector('input[name="tx_host_filterlist[duration]"]:checked'); 43 const d = checked ? parseInt(checked.value, 10) : NaN; 44 return Number.isNaN(d) ? 0 : d; 45 }; 46 47 const lockFilter = (date) => { 48 const d = atMidnight(new Date(date.getFullYear(), date.getMonth(), date.getDate())); 49 const min = minDate; // fix 50 const maxStr = startDateInput.dataset.maxDate || toISO(initialMax); 51 const max = atMidnight(maxStr); 52 53 return (d < min) || (d > max); 54 }; 55 56 const commonOptions = { 57 element: "#startDate", 58 css: ["https://cdn.jsdelivr.net/npm/@easepick/[email protected]/dist/index.css"], 59 zIndex: 10001, 60 lang: "de-DE", 61 format: "YYYY-MM-DD", 62 grid: 2, 63 calendars: 2, 64 header: isPauschDetail ? "Anreisedatum wählen" : "Datum wählen", 65 minDate: toISO(minDate), 66 maxDate: toISO(initialMax), 67 AmpPlugin: { 68 dropdown: { months: false, maxYear: atMidnight(initialMax).getFullYear() }, 69 resetButton: true, 70 darkMode: false, 71 }, 72 LockPlugin: { 73 minDate: toISO(minDate), 74 maxDate: toISO(initialMax), 75 maxDays: maxSpan, 76 selectForward: true, 77 inseparable: true, 78 filter: lockFilter, 79 }, 80 setup(picker) { 81 const startVal = document.querySelector("#startDate")?.value; 82 if (startVal) picker.gotoDate(startVal); 83 84 picker.on("show", () => document.body.classList.add("overflow-hidden")); 85 picker.on("hide", () => document.body.classList.remove("overflow-hidden")); 86 87 if (isPauschDetail) { 88 picker.on("select", (e) => { 89 if (e.detail.start) picker.setDate(e.detail.start); 90 const start = document.querySelector("#startDate"); 91 start.dispatchEvent(new Event("change")); 92 picker.hide(); 93 }); 94 } else { 95 picker.on("preselect", (e) => { 96 if (e.detail.start && e.detail.end) { 97 picker.setStartDate(e.detail.start); 98 picker.setEndDate(e.detail.end); 99 } 100 }); 101 } 102 103 if (document.querySelector('.tx_hosts.host_list.hosts_filter, .tx_hosts.host-detail')) { 104 picker.on("select", () => { 105 const startDate = document.getElementById('startDate'); 106 const endDate = document.getElementById('endDate'); 107 const startDisp = document.getElementById('startDateDisplay'); 108 const endDisp = document.getElementById('endDateDisplay'); 109 110 const updateDisplay = (input, display) => { 111 if (!input || !display) return; 112 if (input.value) { 113 const d = atMidnight(input.value); 114 const val = d.toLocaleDateString('de-DE'); 115 display.value = val; 116 display.setAttribute('value', val); 117 } else { 118 display.value = ''; 119 } 120 }; 121 122 updateDisplay(startDate, startDisp); 123 updateDisplay(endDate, endDisp); 124 startDate?.addEventListener('input', () => updateDisplay(startDate, startDisp)); 125 endDate?.addEventListener('input', () => updateDisplay(endDate, endDisp)); 126 }); 127 } 128 }, 129 plugins: ["AmpPlugin", "KbdPlugin", "LockPlugin"], 130 }; 131 132 if (!isPauschDetail) { 133 commonOptions.plugins.push("RangePlugin"); 134 commonOptions.RangePlugin = { 135 elementEnd: endDateInput, 136 tooltipNumber(num) { return num - 1; }, 137 locale: { one: "Nacht", other: "Nächte" }, 138 maxSpan: { days: maxSpan }, 139 }; 140 commonOptions.autoApply = false;
141 } 142 143 const picker = new easepick.create(commonOptions); 144 window.easePickerInstance = picker; 145 146 const radios = document.querySelectorAll('input[name="tx_host_filterlist[duration]"]'); 147 148 const baseEndStr = startDateInput.dataset.maxDate || toISO(initialMax); 149 const baseEndDate = atMidnight(baseEndStr); 150 151 const updateMaxDate = (duration) => { 152 const baseEnd = new Date(baseEndDate); 153 const min = minDate; 154 const newEnd = new Date(baseEnd); 155 newEnd.setDate(newEnd.getDate() - (Number.isFinite(duration) ? duration : 0)); 156 157 if (newEnd < min) newEnd.setTime(min.getTime()); 158 const iso = toISO(newEnd); 159 160 startDateInput.dataset.maxDate = iso; 161 162 if (startDateInput.value && atMidnight(startDateInput.value) > newEnd) { 163 startDateInput.value = iso; 164 startDateInput.dispatchEvent(new Event('change')); 165 } 166 167 if (typeof picker.renderAll === 'function') picker.renderAll(); 168 169 if (debug) { 170 console.log('[easepick] duration:', duration, 171 '| baseEnd:', toISO(baseEnd), 172 '| min:', toISO(min), 173 '| new max:', iso); 174 } 175 }; 176 177 const checked = document.querySelector('input[name="tx_host_filterlist[duration]"]:checked'); 178 if (checked) { 179 const d = parseInt(checked.value, 10); 180 if (!Number.isNaN(d)) updateMaxDate(d); 181 } 182 183 radios.forEach(r => { 184 r.addEventListener('change', () => { 185 const d = parseInt(r.value, 10); 186 if (!Number.isNaN(d)) updateMaxDate(d); 187 }); 188 }); 189 190 if (document.querySelector('.filter-calender .mobile')) { 191 document.querySelector('.filter-calender .mobile').addEventListener('click', () => picker.show()); 192 } 193 194 if (!isPauschDetail) { 195 picker.on("select", () => { 196 document.querySelector("#startDate")?.dispatchEvent(new Event("change")); 197 document.querySelector("#endDate")?.dispatchEvent(new Event("change")); 198 }); 199 } 200} 201 202document.addEventListener("DOMContentLoaded", () => { 203 let interval = setInterval(() => { 204 const wrapper = document.querySelector(".easepick-wrapper"); 205 const closeBtn = wrapper?.shadowRoot?.querySelector(".btn-close"); 206 if (closeBtn) { 207 closeBtn.addEventListener("click", () => { 208 document.body.classList.remove("overflow-hidden"); 209 }); 210 clearInterval(interval); 211 } 212 }, 200); 213});
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.