PageSourceSearch

https://www.ferienregion-nationalpark.de/_assets/67513b552291f200f…/extensions/calender-plugin.js?1772641963

js ferienregion-nationalpark.de collected 2026-10-09 17:13:57 UTC 6,833 bytes, 213 lines download raw bytes

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.