if (typeof isWasmEnv2 === 'undefined') { var isWasmEnv2 = typeof isGoerpWasm !== 'undefined' && isGoerpWasm; } if (!isWasmEnv2) { document.addEventListener("DOMContentLoaded", function () { const todayTranslation = document.getElementById('datepicker--today-translation')?.value || 'Today'; const accountFormat = document.getElementById('datepicker--date-format')?.value || '02.01.2006'; /* ------------- Calendar Modal ---------------------------*/ document.querySelectorAll('.calendar-container').forEach((el) => { const calendarEl = el.querySelector('.customTimeframe-modal'); if (!calendarEl) return; // if modal is missing const isSingleMode = calendarEl.classList.contains('datepicker--single'); const calendarOpenButton = el.querySelector('.open-customTimeframe-modal'); const calendarCloseButton = el.querySelector('.customTimeframe-close'); const customDateTimePrev = calendarEl.querySelector('.customDatepicker-previous'); const customDateTimeNext = calendarEl.querySelector('.customDatepicker-next'); const customMonthSelector = calendarEl.querySelector('.customMonth-selector'); const customYearSelector = calendarEl.querySelector('.customYear-selector'); const displayEl = calendarEl.querySelector('.customSelected-range-display'); let selectedYear = parseInt(customYearSelector.value, 10); let selectedMonth = parseInt(customMonthSelector.value, 10); let isStartDateSelected = false; // Closing button calendarCloseButton?.addEventListener('click', () => { calendarEl.classList.add('hidden'); }) // Open modal calendarOpenButton?.addEventListener('click', () => { calendarEl.classList.remove('hidden'); }) // Close if clicked outside of modal document.addEventListener('click', function (event) { if (calendarEl && !calendarEl.contains(event.target) && event.target !== calendarOpenButton && !event.target.matches('.customDatepicker-table-date')) { calendarEl.classList.add('hidden'); } }); // Generate calendar on load generateCalendar(selectedYear, selectedMonth, calendarEl, customMonthSelector, customYearSelector); updateDisplay(displayEl, calendarEl.querySelector('.customStart-input').value, calendarEl.querySelector('.customEnd-input').value); // Previous month button customDateTimePrev?.addEventListener('click', () => { selectedMonth--; if (selectedMonth < 0) { selectedMonth = 11; selectedYear--; } generateCalendar(selectedYear, selectedMonth, calendarEl, customMonthSelector, customYearSelector); updateNavButtons(customDateTimePrev, customDateTimeNext, selectedYear, selectedMonth, customYearSelector, customMonthSelector); }); // Next month button customDateTimeNext?.addEventListener('click', () => { selectedMonth++; if (selectedMonth > 11) { selectedMonth = 0; selectedYear++; } generateCalendar(selectedYear, selectedMonth, calendarEl, customMonthSelector, customYearSelector); updateNavButtons(customDateTimePrev, customDateTimeNext, selectedYear, selectedMonth, customYearSelector, customMonthSelector); }); // Handle manual change in select inputs customMonthSelector?.addEventListener('change', () => { selectedMonth = parseInt(customMonthSelector.value, 10); generateCalendar(selectedYear, selectedMonth, calendarEl, customMonthSelector, customYearSelector); updateNavButtons(customDateTimePrev, customDateTimeNext, selectedYear, selectedMonth, customYearSelector, customMonthSelector); }); customYearSelector?.addEventListener('change', () => { selectedYear = parseInt(customYearSelector.value, 10); generateCalendar(selectedYear, selectedMonth, calendarEl, customMonthSelector, customYearSelector); updateNavButtons(customDateTimePrev, customDateTimeNext, selectedYear, selectedMonth, customYearSelector, customMonthSelector); }); // On clicking on calendar date calendarEl.querySelector('.customCalendar')?.addEventListener('click', (e) => { if (e.target.classList.contains('customDatepicker-table-date')) { let selectedDate = e.target.getAttribute('data-date'); if (isSingleMode) { // SINGLE DATE MODE: Only one date is selectable at a time calendarEl.querySelector('.customStart-input').value = selectedDate; if (calendarEl.querySelector('.customEnd-input')) { calendarEl.querySelector('.customEnd-input').value = ""; // Clear end input } isStartDateSelected = true; // Force UI update by removing and adding the selected class calendarEl.querySelectorAll('.customDatepicker-table-date').forEach(dateCell => { dateCell.classList.remove('customDate-selected'); }); e.target.classList.add('customDate-selected'); // Add selected class to the clicked date // Ensure the displayed date updates immediately updateDisplay(displayEl, selectedDate, null); } else { let selectedDate = e.target.getAttribute('data-date'); let startDate = calendarEl.querySelector('.customStart-input'); let endDate = calendarEl.querySelector('.customEnd-input'); let selectedDateObj = new Date(selectedDate); let startDateObj = new Date(startDate.value); let endDateObj = new Date(endDate.value); // If none is selected if (!isStartDateSelected) { startDate.value = selectedDate; endDate.value = selectedDate; isStartDateSelected = true; } // If range is selected and end date is LESS than selected date - extend range else if (startDate.value && endDate.value && selectedDateObj > endDateObj) { endDate.value = selectedDate; } // If range is selected and start date is BIGGER than selected date - extend range // Or // If range is selected and end date is selected again - set start date as end date else if ( startDate.value && endDate.value && selectedDateObj < startDateObj || startDate.value && endDate.value && selectedDate == endDate.value ) { startDate.value = selectedDate; } // If selected date inside the selected date range else { endDate.value = selectedDate; } generateCalendar(selectedYear, selectedMonth, calendarEl, customMonthSelector, customYearSelector); updateDisplay(displayEl, startDate.value, endDate.value); calendarEl.querySelector(`[tabindex="${e.target.getAttribute('tabindex')}"]`)?.focus(); } } }); function formatDateByAccountFormat(dateObj) { const dd = String(dateObj.getDate()).padStart(2, "0"); const mm = String(dateObj.getMonth() + 1).padStart(2, "0"); const yyyy = dateObj.getFullYear(); const tokenMap = { "02": dd, "01": mm, "2006": yyyy }; // Replace tokens in ONE pass, longest first return accountFormat.replace(/2006|02|01/g, token => tokenMap[token]); } function getDateFormatByAccountFormat() { const tokenMap = { "02": "dd", "01": "mm", "2006": "yyyy" }; // Replace tokens in ONE pass, longest first return accountFormat.replace(/2006|02|01/g, token => tokenMap[token]); } function updateDisplay(displayEl, startDate, endDate) { if (!startDate && !endDate) { displayEl.innerText = getDateFormatByAccountFormat(); calendarOpenButton.innerText = getDateFormatByAccountFormat(); return; } const startDateObj = new Date(startDate); const endDateObj = new Date(endDate); // Invalid date check if (isNaN(startDateObj.getTime()) && !endDate) { displayEl.innerText = startDate; calendarOpenButton.innerText = startDate; return; } const startFormatted = formatDateByAccountFormat(startDateObj); let date = startFormatted; if ( endDate && startDateObj.toDateString() !== endDateObj.toDateString() ) { const endFormatted = formatDateByAccountFormat(endDateObj); date += " - " + endFormatted; } displayEl.innerText = date; calendarOpenButton.innerText = date; } const today = new Date(); const yesterday = new Date(today); yesterday.setDate(today.getDate() - 1); // This week const weekStart = new Date(today); weekStart.setDate(today.getDate() - today.getDay() + 1); // Monday const weekEnd = new Date(weekStart); weekEnd.setDate(weekStart.getDate() + 6); // Sunday // This month const monthStart = new Date(today.getFullYear(), today.getMonth(), 1); const monthEnd = new Date(today.getFullYear(), today.getMonth() + 1, 0); // Previous week const prevWeekEnd = new Date(weekStart); prevWeekEnd.setDate(weekStart.getDate() - 1); // Last Sunday const prevWeekStart = new Date(prevWeekEnd); prevWeekStart.setDate(prevWeekEnd.getDate() - 6); // Monday // Previous month const prevMonthEnd = new Date(today.getFullYear(), today.getMonth(), 0); const prevMonthStart = new Date(today.getFullYear(), today.getMonth() - 1, 1); // Reset const resetButton = calendarEl.querySelector('.customDatepicker-reset'); if (resetButton) { resetButton.addEventListener('click', () => { clearDateRange(); }); resetButton.addEventListener('keydown', (event) => { if (event.key === 'Enter' || event.key === ' ') { clearDateRange(); } }); } // Add functionality to datepicker buttons const dateButtons = [ { selector: '.customDatepick-today', dateRange: [formatDate(today), formatDate(today)] }, { selector: '.customDatepick-yesterday', dateRange: [formatDate(yesterday), formatDate(yesterday)] }, { selector: '.customDatepick-week', dateRange: [formatDate(weekStart), formatDate(weekEnd)] }, { selector: '.customDatepick-month', dateRange: [formatDate(monthStart), formatDate(monthEnd)] }, { selector: '.customDatepick-prevweek', dateRange: [formatDate(prevWeekStart), formatDate(prevWeekEnd)] }, { selector: '.customDatepick-prevmonth', dateRange: [formatDate(prevMonthStart), formatDate(prevMonthEnd)] } ]; // Add the clearDateRange function function clearDateRange() { calendarEl.querySelector('.customStart-input').value = ''; calendarEl.querySelector('.customEnd-input').value = ''; // Update display to show placeholder or empty state if (displayEl) { displayEl.innerText = getDateFormatByAccountFormat(); } if (calendarOpenButton) { calendarOpenButton.innerText = getDateFormatByAccountFormat(); } // Regenerate to remove selected styling and reset to allow new selection generateCalendar(selectedYear, selectedMonth, calendarEl, customMonthSelector, customYearSelector); isStartDateSelected = false; } dateButtons.forEach(({ selector, dateRange }) => { const element = calendarEl.querySelector(selector); if (element) { element.addEventListener('click', () => { setDateRange(dateRange[0], dateRange[1]); }); element.addEventListener('keydown', (event) => { if (event.key === 'Enter' || event.key === ' ') { setDateRange(dateRange[0], dateRange[1]); } }); } }); function setDateRange(startDate, endDate) { const startDateObj = new Date(startDate); calendarEl.querySelector('.customStart-input').value = startDate; calendarEl.querySelector('.customEnd-input').value = endDate; const selectedYear = startDateObj.getFullYear(); const selectedMonth = startDateObj.getMonth(); generateCalendar(selectedYear, selectedMonth, calendarEl, customMonthSelector, customYearSelector); isStartDateSelected = true; updateDisplay( displayEl, calendarEl.querySelector('.customStart-input').value, calendarEl.querySelector('.customEnd-input').value ); } }); // Generate calendar function generateCalendar(year, month, calendarEl, customMonthSelector, customYearSelector, isSingleMode) { const calendarContent = calendarEl.querySelector('.customCalendar'); calendarContent.innerHTML = ""; // Clear previous content const today = new Date(); // Adjust first day to match Monday start (shift Sunday index 0 to 6) let firstDay = new Date(year, month, 1).getDay(); firstDay = (firstDay === 0) ? 6 : firstDay - 1; const lastDate = new Date(year, month + 1, 0).getDate(); const prevLastDate = new Date(year, month, 0).getDate(); let html = '