PageSourceSearch

https://plus.badi.com/wp-content/plugins/hostify-booking/public/res/datepicker.js?ver=0.8.4

js badi.com collected 2026-09-24 09:07:36 UTC 23,178 bytes, 699 lines download raw bytes

1// Global datepicker instance will be stored in window.hotelDatepicker
2
3// Removed redundant getRequiredMinStayForDate function. Library handles this internally now.
4
5document.addEventListener('DOMContentLoaded', function () {
6	// Check if HotelDatepicker is available
7	if (typeof HotelDatepicker !== 'function') {
8		console.warn(
9			'HotelDatepicker not found. Skipping datepicker initialization.'
10		);
11		return;
12	}
13
14	// --- DEBUG: Log global variables ---
15	// console.log('DEBUG: Initial value of calendarCustomStay:', typeof calendarCustomStay !== 'undefined' ? JSON.stringify(calendarCustomStay) : 'undefined');
16	// console.log('DEBUG: Initial value of minNights:', typeof minNights !== 'undefined' ? minNights : 'undefined');
17	// console.log('DEBUG: Initial value of maxNights:', typeof maxNights !== 'undefined' ? maxNights : 'undefined');
18	// console.log('DEBUG: Initial value of hfyArgs:', typeof hfyArgs !== 'undefined' ? JSON.stringify(hfyArgs) : 'undefined');
19	// console.log('DEBUG: hfyx.use_v3_calendar:', typeof hfyx !== 'undefined' ? hfyx.use_v3_calendar : 'undefined');
20	// --- END DEBUG ---
21
22	var currentSelectionStartDate = null; // Variable to hold the start date during selection
23
24	// Process disabled dates from global variable
25	var formattedDisabledDates = [];
26	if (
27		typeof calendarDisabledDates !== 'undefined' &&
28		Array.isArray(calendarDisabledDates)
29	) {
30		calendarDisabledDates.forEach(function (dateItem) {
31			if (
32				typeof dateItem === 'string' &&
33				/^\d{4}-\d{2}-\d{2}$/.test(dateItem)
34			) {
35				formattedDisabledDates.push(dateItem);
36			} else if (dateItem instanceof Date) {
37				try {
38					formattedDisabledDates.push(
39						fecha.format(dateItem, 'YYYY-MM-DD')
40					);
41				} catch (e) {
42					console.warn(
43						'Could not format Date object from calendarDisabledDates:',
44						dateItem,
45						e
46					);
47				}
48			} else if (
49				typeof dateItem === 'object' &&
50				dateItem !== null &&
51				dateItem.start &&
52				dateItem.end &&
53				typeof dateItem.start === 'string' &&
54				typeof dateItem.end === 'string'
55			) {
56				try {
57					var rangeStartDate = fecha.parse(
58						dateItem.start,
59						'YYYY-MM-DD'
60					); // Renamed to avoid conflict
61					var rangeEndDate = fecha.parse(dateItem.end, 'YYYY-MM-DD'); // Renamed to avoid conflict
62					if (
63						rangeStartDate &&
64						rangeEndDate &&
65						rangeStartDate <= rangeEndDate
66					) {
67						var currentDate = new Date(rangeStartDate);
68						while (currentDate <= rangeEndDate) {
69							formattedDisabledDates.push(
70								fecha.format(currentDate, 'YYYY-MM-DD')
71							);
72							currentDate.setDate(currentDate.getDate() + 1);
73						}
74					} else {
75						console.warn(
76							'Invalid date range object in calendarDisabledDates:',
77							dateItem
78						);
79					}
80				} catch (e) {
81					console.warn(
82						'Could not parse date range object from calendarDisabledDates:',
83						dateItem,
84						e
85					);
86				}
87			} else if (
88				typeof dateItem === 'object' &&
89				dateItem !== null &&
90				typeof dateItem.format === 'function'
91			) {
92				try {
93					formattedDisabledDates.push(dateItem.format('YYYY-MM-DD'));
94				} catch (e) {
95					console.warn(
96						'Could not format moment-like object from calendarDisabledDates:',
97						dateItem,
98						e
99					);
100				}
101			} else {
102				console.warn(
103					'Ignoring invalid item in calendarDisabledDates:',
104					dateItem
105				);
106			}
107		});
108	} else if (typeof calendarDisabledDates !== 'undefined') {
109		console.warn(
110			'calendarDisabledDates is defined but not an array:',
111			calendarDisabledDates
112		);
113	}
114
115	// Get default minNights from global variable
116	var defaultMinNights =
117		typeof minNights !== 'undefined' &&
118		Number.isInteger(parseInt(minNights)) &&
119		parseInt(minNights) > 0
120			? parseInt(minNights)
121			: 1;
122
123	// Process disabled days of week from global variable (hfyArgs)
124	var disabledDaysOfWeek =
125		typeof hfyArgs !== 'undefined' &&
126		Array.isArray(hfyArgs.disabledWeekDays)
127			? hfyArgs.disabledWeekDays
128			: [];
129
130	// Process no check-in/check-out days of week from global variable (hfyArgs)
131	// Note: The old code used calendarInDays/calendarOutDays bitmasks. We'll use hfyArgs.daysOfWeekDisabled for both now.
132	var noCheckInDaysOfWeek =
133		typeof hfyArgs !== 'undefined' &&
134		Array.isArray(hfyArgs.daysOfWeekDisabled)
135			? hfyArgs.daysOfWeekDisabled
136			: [];
137	var noCheckOutDaysOfWeek =
138		typeof hfyArgs !== 'undefined' &&
139		Array.isArray(hfyArgs.daysOfWeekDisabled)
140			? hfyArgs.daysOfWeekDisabled
141			: []; // Assuming same as check-in for now
142
143	// Process specific no check-in/check-out dates from global variables
144	var noCheckInDates =
145		typeof calendarOverInDays !== 'undefined' &&
146		Array.isArray(calendarOverInDays)
147			? calendarOverInDays.map(d => (typeof d === 'string' ? d : ''))
148			: [];
149	var noCheckOutDates =
150		typeof calendarOverOutDays !== 'undefined' &&
151		Array.isArray(calendarOverOutDays)
152			? calendarOverOutDays.map(d => (typeof d === 'string' ? d : ''))
153			: [];
154	// Filter out any empty strings resulting from non-string items
155	noCheckInDates = noCheckInDates.filter(d => d !== '');
156	noCheckOutDates = noCheckOutDates.filter(d => d !== '');
157
158	// Get maxNights from global variable
159	var defaultMaxNights =
160		typeof maxNights !== 'undefined' &&
161		Number.isInteger(parseInt(maxNights)) &&
162		parseInt(maxNights) >= 0
163			? parseInt(maxNights)
164			: 0;
165
166	// Basic mobile check
167	var isMob = window.innerWidth <= 768;
168
169	// Define options for the datepicker
170	var options = {
171		showTopbar: false,
172		clearButton: false,
173		format: 'YYYY-MM-DD',
174		startOfWeek: 'monday',
175		minNights: 1, // Set base minNights to 1, rely on calendarCustomStay for specifics
176		maxNights: defaultMaxNights,
177		selectForward: true, // Changed based on review
178		autoClose: true, // Changed based on review
179		moveBothMonths: true, // Changed based on review
180		disabledDates: formattedDisabledDates,
181		enableCheckout: true,
182		disabledDaysOfWeek: disabledDaysOfWeek,
183		noCheckInDaysOfWeek: noCheckInDaysOfWeek,
184		noCheckOutDaysOfWeek: noCheckOutDaysOfWeek,
185		noCheckInDates: noCheckInDates, // Added
186		noCheckOutDates: noCheckOutDates, // Added
187		animationSpeed: '.3s',
188		// hoveringTooltip: true, // Use library's default tooltip which now respects dynamic minNights
189		calendarCustomStay:
190			typeof calendarCustomStay !== 'undefined' ? calendarCustomStay : [], // Pass custom stay rules
191
192		// Mobile-specific options
193		mobileMonthsToShow: 6, // Show 6 months initially on mobile
194		mobileMonthsToLoad: 24, // Pre-load 12 months total
195		onDayClick: function (event, date) {
196			var datepicker = window.hotelDatepicker;
197			if (datepicker && !datepicker.getValue()) {
198				currentSelectionStartDate = date;
199			} else {
200				currentSelectionStartDate = null;
201			}
202		},
203		onSelectRange: function () {
204			currentSelectionStartDate = null; // Reset on range selection complete
205			updateFormAndPrices();
206		},
207		onOpenDatepicker: function () {
208			// Apply custom arrow logic for consecutive months every time the calendar opens
209			setTimeout(() => {
210				const datepicker = window.hotelDatepicker;
211				if (!datepicker) return;
212
213				const datepickerElement = datepicker.datepicker;
214				const nextButtons = datepickerElement.getElementsByClassName(
215					'datepicker__month-button--next'
216				);
217				const prevButtons = datepickerElement.getElementsByClassName(
218					'datepicker__month-button--prev'
219				);
220
221				// First, let the library apply its logic
222				if (datepicker.disableNextPrevButtons) {
223					datepicker.disableNextPrevButtons();
224				}
225
226				// Then apply the custom logic for consecutive months
227				if (nextButtons.length >= 2 && prevButtons.length >= 2) {
228					// Hide left arrow of first month (except when we can go back)
229					const canGoBack =
230						datepicker.month1 &&
231						!datepicker.isMonthOutOfRange(
232							datepicker.getPrevMonth(datepicker.month1)
233						);
234					if (!canGoBack) {
235						datepicker.addClass(
236							prevButtons[0],
237							'datepicker__month-button--disabled'
238						);
239						prevButtons[0].setAttribute('aria-disabled', 'true');
240					}
241
242					// Hide right arrow of first month (always, since we want both months to move together)
243					datepicker.addClass(
244						nextButtons[0],
245						'datepicker__month-button--disabled'
246					);
247					nextButtons[0].setAttribute('aria-disabled', 'true');
248
249					// Hide left arrow of second month (always, since we want both months to move together)
250					datepicker.addClass(
251						prevButtons[1],
252						'datepicker__month-button--disabled'
253					);
254					prevButtons[1].setAttribute('aria-disabled', 'true');
255
256					// Right arrow of second month - keep enabled if we can go forward
257					const canGoForward =
258						datepicker.month2 &&
259						!datepicker.isMonthOutOfRange(
260							datepicker.getNextMonth(datepicker.month2)
261						);
262					if (canGoForward) {
263						datepicker.removeClass(
264							nextButtons[1],
265							'datepicker__month-button--disabled'
266						);
267						nextButtons[1].setAttribute('aria-disabled', 'false');
268					}
269				}
270			}, 50);
271		},
272		// getMinStayFunction: getRequiredMinStayForDate // We are not modifying the library anymore
273	};
274
275	// Merge translated month/day names into options BEFORE creating HotelDatepicker.
276	// This ensures the initial render (including weekdays) uses the correct language.
277	if (typeof hfyTranslations !== 'undefined') {
278		var defaultI18n = {
279			selected: 'Your stay:',
280			night: 'Night',
281			nights: 'Nights',
282			button: 'Close',
283			clearButton: 'Clear',
284			submitButton: 'Submit',
285			'checkin-disabled': 'Check-in disabled',
286			'checkout-disabled': 'Check-out disabled',
287			'day-names-short': [
288				'Sun',
289				'Mon',
290				'Tue',
291				'Wed',
292				'Thu',
293				'Fri',
294				'Sat',
295			],
296			'day-names': [
297				'Sunday',
298				'Monday',
299				'Tuesday',
300				'Wednesday',
301				'Thursday',
302				'Friday',
303				'Saturday',
304			],
305			'month-names-short': [
306				'Jan',
307				'Feb',
308				'Mar',
309				'Apr',
310				'May',
311				'Jun',
312				'Jul',
313				'Aug',
314				'Sep',
315				'Oct',
316				'Nov',
317				'Dec',
318			],
319			'month-names': [
320				'January',
321				'February',
322				'March',
323				'April',
324				'May',
325				'June',
326				'July',
327				'August',
328				'September',
329				'October',
330				'November',
331				'December',
332			],
333			'error-more': 'Date range should not be more than 1 night',
334			'error-more-plural': 'Date range should not be more than %d nights',
335			'error-less': 'Date range should not be less than 1 night',
336			'error-less-plural': 'Date range should not be less than %d nights',
337			'info-more': 'Please select a date range of at least 1 night',
338			'info-more-plural':
339				'Please select a date range of at least %d nights',
340			'info-range': 'Please select a date range between %d and %d nights',
341			'info-range-equal': 'Please select a date range of %d nights',
342			'info-default': 'Please select a date range',
343			'aria-application': 'Calendar',
344			'aria-selected-checkin': 'Selected as check-in date, %s',
345			'aria-selected-checkout': 'Selected as check-out date, %s',
346			'aria-selected': 'Selected, %s',
347			'aria-disabled': 'Not available, %s',
348			'aria-choose-checkin': 'Choose %s as your check-in date',
349			'aria-choose-checkout': 'Choose %s as your check-out date',
350			'aria-prev-month': 'Move backward to switch to the previous month',
351			'aria-next-month': 'Move forward to switch to the next month',
352			'aria-close-button': 'Close the datepicker',
353			'aria-clear-button': 'Clear the selected dates',
354			'aria-submit-button': 'Submit the form',
355		};
356		options.i18n = Object.assign({}, defaultI18n);
357		if (
358			hfyTranslations.monthNames &&
359			hfyTranslations.monthNames.length === 12
360		) {
361			options.i18n['month-names'] = hfyTranslations.monthNames;
362		}
363		if (
364			hfyTranslations.monthNamesShort &&
365			hfyTranslations.monthNamesShort.length === 12
366		) {
367			options.i18n['month-names-short'] = hfyTranslations.monthNamesShort;
368		}
369		if (hfyTranslations.dayNames && hfyTranslations.dayNames.length === 7) {
370			options.i18n['day-names'] = hfyTranslations.dayNames;
371		}
372		if (
373			hfyTranslations.dayNamesShort &&
374			hfyTranslations.dayNamesShort.length === 7
375		) {
376			options.i18n['day-names-short'] = hfyTranslations.dayNamesShort;
377		}
378		if (typeof hfyTranslations.night !== 'undefined') {
379			options.i18n.night = hfyTranslations.night;
380		}
381		if (typeof hfyTranslations.nights !== 'undefined') {
382			options.i18n.nights = hfyTranslations.nights;
383		}
384		if (typeof hfyTranslations.selected !== 'undefined') {
385			options.i18n.selected = hfyTranslations.selected;
386		}
387		if (typeof hfyTranslations.button !== 'undefined') {
388			options.i18n.button = hfyTranslations.button;
389		}
390		if (typeof hfyTranslations.clearButton !== 'undefined') {
391			options.i18n.clearButton = hfyTranslations.clearButton;
392		}
393		if (typeof hfyTranslations.submitButton !== 'undefined') {
394			options.i18n.submitButton = hfyTranslations.submitButton;
395		}
396		if (typeof hfyTranslations.errorMore !== 'undefined') {
397			options.i18n['error-more'] = hfyTranslations.errorMore;
398		}
399		if (typeof hfyTranslations.errorMorePlural !== 'undefined') {
400			options.i18n['error-more-plural'] = hfyTranslations.errorMorePlural;
401		}
402		if (typeof hfyTranslations.errorLess !== 'undefined') {
403			options.i18n['error-less'] = hfyTranslations.errorLess;
404		}
405		if (typeof hfyTranslations.errorLessPlural !== 'undefined') {
406			options.i18n['error-less-plural'] = hfyTranslations.errorLessPlural;
407		}
408		if (typeof hfyTranslations.infoMore !== 'undefined') {
409			options.i18n['info-more'] = hfyTranslations.infoMore;
410		}
411		if (typeof hfyTranslations.infoMorePlural !== 'undefined') {
412			options.i18n['info-more-plural'] = hfyTranslations.infoMorePlural;
413		}
414		if (typeof hfyTranslations.infoRange !== 'undefined') {
415			options.i18n['info-range'] = hfyTranslations.infoRange;
416		}
417		if (typeof hfyTranslations.infoRangeEqual !== 'undefined') {
418			options.i18n['info-range-equal'] = hfyTranslations.infoRangeEqual;
419		}
420		if (typeof hfyTranslations.infoDefault !== 'undefined') {
421			options.i18n['info-default'] = hfyTranslations.infoDefault;
422		}
423	}
424
425	// --- Prepare initial value for the datepicker input if dates are pre-filled ---
426	var mainDateInput = document.getElementById('hotel-datepicker');
427	var initialStartDateInputPrep = document.querySelector(
428		'input[name="start_date"]'
429	); // Use different var name to avoid conflict later
430	var initialEndDateInputPrep = document.querySelector(
431		'input[name="end_date"]'
432	);
433
434	if (
435		mainDateInput &&
436		initialStartDateInputPrep &&
437		initialStartDateInputPrep.value &&
438		initialEndDateInputPrep &&
439		initialEndDateInputPrep.value
440	) {
441		var startDateStr = initialStartDateInputPrep.value;
442		var endDateStr = initialEndDateInputPrep.value;
443		var formattedStartDate = null;
444		var formattedEndDate = null;
445
446		// --- Roo: Try parsing YYYY-MM-DD first ---
447		if (
448			/^\d{4}-\d{2}-\d{2}$/.test(startDateStr) &&
449			/^\d{4}-\d{2}-\d{2}$/.test(endDateStr)
450		) {
451			try {
452				// Use fecha to be sure they are valid dates, even if format matches regex
453				var d1 = fecha.parse(startDateStr, 'YYYY-MM-DD');
454				var d2 = fecha.parse(endDateStr, 'YYYY-MM-DD');
455				if (d1 && d2 && d1 < d2) {
456					formattedStartDate = startDateStr;
457					formattedEndDate = endDateStr;
458				}
459			} catch (e) {
460				/* Ignore parsing errors here */
461			}
462		}
463
464		// --- Roo: If YYYY-MM-DD failed or was invalid, try DD-MM-YYYY ---
465		if (
466			!formattedStartDate &&
467			/^\d{2}-\d{2}-\d{4}$/.test(startDateStr) &&
468			/^\d{2}-\d{2}-\d{4}$/.test(endDateStr)
469		) {
470			try {
471				var d1 = fecha.parse(startDateStr, 'DD-MM-YYYY');
472				var d2 = fecha.parse(endDateStr, 'DD-MM-YYYY');
473				if (d1 && d2 && d1 < d2) {
474					// Reformat to the expected YYYY-MM-DD for the input and datepicker library
475					formattedStartDate = fecha.format(d1, 'YYYY-MM-DD');
476					formattedEndDate = fecha.format(d2, 'YYYY-MM-DD');
477				}
478			} catch (e) {
479				/* Ignore parsing errors here */
480			}
481		}
482
483		// --- Roo: Set the input value if we successfully parsed and formatted dates ---
484		if (formattedStartDate && formattedEndDate) {
485			mainDateInput.value = formattedStartDate + ' - ' + formattedEndDate;
486			// console.log('DEBUG: Pre-setting #hotel-datepicker value to:', mainDateInput.value);
487		} else {
488			// console.warn('Could not parse or validate initial start/end dates from hidden inputs. Not pre-setting value.', { start: startDateStr, end: endDateStr });
489		}
490	}
491	// --- End preparation ---
492
493	// Initialize the datepicker only if the element exists
494	if (mainDateInput && typeof HotelDatepicker === 'function') {
495		// Initialize the datepicker (use the mainDateInput variable which might have updated value)
496		// options.i18n is already set above with translated month/day names, so initial render uses correct language
497		var datepicker = new HotelDatepicker(mainDateInput, options);
498
499		// Store the datepicker instance globally
500		window.hotelDatepicker = datepicker;
501
502		// Fix: Ensure month1 and month2 are set for main datepicker
503		if (!datepicker.month1 || !datepicker.month2) {
504			var defaultTime = new Date();
505			datepicker.month1 = new Date(defaultTime);
506			datepicker.month2 = new Date(defaultTime);
507			datepicker.month2.setMonth(datepicker.month2.getMonth() + 1);
508		}
509
510		// Handle clear dates button
511		var resetDateButton = document.querySelector('.reset-date');
512		if (resetDateButton && datepicker) {
513			resetDateButton.addEventListener('click', function () {
514				datepicker.clear();
515				clearFormDates();
516			});
517		}
518
519		// Listen for the afterClose event (redundant if onSelectRange works, but safe)
520		if (mainDateInput) {
521			mainDateInput.addEventListener('afterClose', function () {
522				// Check if dates are actually selected before updating
523				if (datepicker && datepicker.getValue()) {
524					updateFormAndPrices();
525				}
526			});
527		}
528
529		// Trigger initial update if dates are pre-filled on load
530		var initialStartDateInput = document.querySelector(
531			'input[name="start_date"]'
532		);
533		var initialEndDateInput = document.querySelector(
534			'input[name="end_date"]'
535		);
536		if (
537			initialStartDateInput &&
538			initialStartDateInput.value &&
539			initialEndDateInput &&
540			initialEndDateInput.value
541		) {
542			setTimeout(function () {
543				if (typeof window.doUpdatePriceBlock === 'function') {
544					window.doUpdatePriceBlock();
545				} else if (typeof submitForm === 'function') {
546					submitForm();
547				}
548			}, 0);
549		}
550	}
551
552	// Initialize V3 calendar in hfy-listing-availability div if V3 is enabled
553	if (typeof hfyx !== 'undefined' && hfyx.use_v3_calendar) {
554		var availabilityDiv = document.querySelector(
555			'.hfy-listing-availability'
556		);
557		if (availabilityDiv) {
558			var v3Container = document.getElementById('hotel-datepicker-v3');
559			if (v3Container && typeof HotelDatepicker === 'function') {
560				// Initialize V3 datepicker with same options but modified for direct display
561				var v3Options = Object.assign({}, options, {
562					inline: true, // Make the calendar always visible
563					showTopbar: false,
564					clearButton: false,
565					format: 'YYYY-MM-DD',
566					startOfWeek: 'monday',
567					minNights: 1, // Set base minNights to 1, rely on calendarCustomStay for specifics
568					maxNights: defaultMaxNights,
569					selectForward: true, // Changed based on review
570					autoClose: false, // Don't auto-close since it's always visible
571					moveBothMonths: true, // Changed based on review
572					disabledDates: formattedDisabledDates,
573					enableCheckout: true,
574					disabledDaysOfWeek: disabledDaysOfWeek,
575					noCheckInDaysOfWeek: noCheckInDaysOfWeek,
576					noCheckOutDaysOfWeek: noCheckOutDaysOfWeek,
577					noCheckInDates: noCheckInDates, // Added
578					noCheckOutDates: noCheckOutDates, // Added
579					animationSpeed: '.3s',
580					// hoveringTooltip: true, // Use library's default tooltip which now respects dynamic minNights
581					calendarCustomStay:
582						typeof calendarCustomStay !== 'undefined'
583							? calendarCustomStay
584							: [], // Pass custom stay rules
585
586					// Force desktop mode
587					isMobile: false,
588					isTouchDevice: false,
589
590					// Mobile-specific options
591					// mobileMonthsToShow: 1, // Show only 1 month on mobile - is not working
592					mobileMonthsToLoad: 2, // Pre-load 2 months total
593				});
594
595				// v3Options inherits options (including options.i18n) via Object.assign, so translations are applied
596				var v3Datepicker = new HotelDatepicker(v3Container, v3Options);
597
598				// Override the core dayClicked method to prevent selection
599				v3Datepicker.dayClicked = function () {
600					return false;
601				};
602
603				// Force desktop mode by overriding isMobile property
604				Object.defineProperty(v3Datepicker, 'isMobile', {
605					get: function () {
606						return false; // Always return false to force desktop mode
607					},
608					set: function () {
609						// Prevent setting isMobile
610					},
611				});
612
613				// Override the checkIsMobile function
614				v3Datepicker.checkIsMobile = function () {
615					return false; // Always return false to force desktop mode
616				};
617
618				// Override the isTouchDevice function
619				v3Datepicker.isTouchDevice = function () {
620					return false; // Always return false to force desktop mode
621				};
622
623				// Force initial check and render
624				v3Datepicker.onResizeDatepicker();
625
626				// Fix: Ensure month1 and month2 are set for V3 calendar
627				if (!v3Datepicker.month1 || !v3Datepicker.month2) {
628					var defaultTime = new Date();
629					v3Datepicker.month1 = new Date(defaultTime);
630					v3Datepicker.month2 = new Date(defaultTime);
631					v3Datepicker.month2.setMonth(
632						v3Datepicker.month2.getMonth() + 1
633					);
634				}
635
636				// Fix: Call disableNextPrevButtons for V3 calendar
637				setTimeout(() => {
638					v3Datepicker.disableNextPrevButtons();
639				}, 0);
640			}
641		}
642	}
643});
644
645// Update form hidden fields and trigger price update
646function updateFormAndPrices() {
647	var datepicker = window.hotelDatepicker;
648	if (!datepicker) return;
649
650	var dateValue = datepicker.getValue();
651	if (!dateValue) return;
652
653	var dates = dateValue.split(' - ');
654	var startDateStr = dates[0];
655	var endDateStr = dates.length > 1 ? dates[1] : null;
656
657	// --- Removed redundant Variable Minimum Stay Check ---
658	// The library's internal checkSelection method now handles this validation.
659	// Note: currentSelectionStartDate is reset within onSelectRange or clearFormDates
660
661	// Update hidden input fields
662	var startDateInput = document.querySelector('input[name="start_date"]');
663	var endDateInput = document.querySelector('input[name="end_date"]');
664
665	if (startDateInput && startDateStr) {
666		startDateInput.value = startDateStr;
667	}
668
669	if (endDateInput && endDateStr) {
670		endDateInput.value = endDateStr;
671	}
672
673	// Call submitForm function to update prices
674	if (typeof window.doUpdatePriceBlock === 'function') {
675		window.doUpdatePriceBlock();
676	} else if (typeof submitForm === 'function') {
677		submitForm();
678	}
679}
680
681// Clear form dates and update UI
682function clearFormDates() {
683	// currentSelectionStartDate is reset within onSelectRange or here
684	currentSelectionStartDate = null; // Also clear temp start date
685
686	var startDateInput = document.querySelector('input[name="start_date"]');
687	var endDateInput = document.querySelector('input[name="end_date"]');
688
689	if (startDateInput) startDateInput.value = '';
690	if (endDateInput) endDateInput.value = '';
691
692	// Update URL and prices
693	window.history.replaceState('', '', location.pathname);
694
695	// Call submitForm function to update prices
696	if (typeof window.doUpdatePriceBlock === 'function') {
697		window.doUpdatePriceBlock();
698	}
699}

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.