From 2e8da0be8fcbc8fcb8a45bd27185d45b33dc8e8f Mon Sep 17 00:00:00 2001 From: Aleksandra Bozek Date: Fri, 25 Jul 2025 12:31:06 +0200 Subject: [PATCH 1/3] IBX-6662: Handled re-positioning date picker on scroll --- .../public/js/scripts/admin.picker.js | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/bundle/Resources/public/js/scripts/admin.picker.js b/src/bundle/Resources/public/js/scripts/admin.picker.js index 6e449d44f0..9ea1ede698 100644 --- a/src/bundle/Resources/public/js/scripts/admin.picker.js +++ b/src/bundle/Resources/public/js/scripts/admin.picker.js @@ -2,12 +2,44 @@ const SELECTOR_PICKER = '.ibexa-picker'; const SELECTOR_PICKER_INPUT = '.ibexa-date-time-picker__input'; const SELECTOR_FORM_INPUT = '.ibexa-picker__form-input'; + const SECTION_ADJUSTMENT = 24; + const PICKER_ADJUSTMENT = 2; const pickers = doc.querySelectorAll(SELECTOR_PICKER); const { formatShortDateTime, convertDateToTimezone, getBrowserTimezone } = ibexa.helpers.timezone; const userTimezone = ibexa.adminUiConfig.timezone; const pickerConfig = { enableTime: true, time_24hr: true, + onOpen: (_selectedDates, _dateStr, instance) => { + instance.scrollHandler = () => { + if (instance.isOpen) { + const { calendarContainer } = instance; + const { input } = instance; + const rect = input.getBoundingClientRect(); + const pickerHeight = calendarContainer.offsetHeight; + const spaceBelow = global.innerHeight - (rect.bottom + SECTION_ADJUSTMENT); + + if (pickerHeight > spaceBelow) { + calendarContainer.style.top = `${rect.top + global.scrollY - pickerHeight - PICKER_ADJUSTMENT}px`; + calendarContainer.classList.remove('arrowTop'); + calendarContainer.classList.add('arrowBottom'); + } else { + calendarContainer.style.top = `${rect.bottom + global.scrollY + PICKER_ADJUSTMENT}px`; + calendarContainer.classList.remove('arrowBottom'); + calendarContainer.classList.add('arrowTop'); + } + } + }; + + global.addEventListener('scroll', instance.scrollHandler, true); + doc.addEventListener('scroll', instance.scrollHandler, true); + + instance.scrollHandler(); + }, + onClose: (_selectedDates, _dateStr, instance) => { + global.removeEventListener('scroll', instance.scrollHandler, true); + doc.removeEventListener('scroll', instance.scrollHandler, true); + }, formatDate: (date) => formatShortDateTime(date, null), }; const updateInputValue = (formInput, timestamp) => { From 67466763796db9c6e74d0a3862d817d402eedc09 Mon Sep 17 00:00:00 2001 From: Aleksandra Bozek Date: Wed, 30 Jul 2025 13:47:16 +0200 Subject: [PATCH 2/3] After review --- src/bundle/Resources/public/js/scripts/admin.picker.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/bundle/Resources/public/js/scripts/admin.picker.js b/src/bundle/Resources/public/js/scripts/admin.picker.js index 9ea1ede698..669adcc664 100644 --- a/src/bundle/Resources/public/js/scripts/admin.picker.js +++ b/src/bundle/Resources/public/js/scripts/admin.picker.js @@ -10,11 +10,10 @@ const pickerConfig = { enableTime: true, time_24hr: true, - onOpen: (_selectedDates, _dateStr, instance) => { + onOpen: (selectedDates, dateStr, instance) => { instance.scrollHandler = () => { if (instance.isOpen) { - const { calendarContainer } = instance; - const { input } = instance; + const { calendarContainer, input } = instance; const rect = input.getBoundingClientRect(); const pickerHeight = calendarContainer.offsetHeight; const spaceBelow = global.innerHeight - (rect.bottom + SECTION_ADJUSTMENT); @@ -36,7 +35,7 @@ instance.scrollHandler(); }, - onClose: (_selectedDates, _dateStr, instance) => { + onClose: (selectedDates, dateStr, instance) => { global.removeEventListener('scroll', instance.scrollHandler, true); doc.removeEventListener('scroll', instance.scrollHandler, true); }, From c0a885cf2491ae4e3922c6374816531c9cbd6058 Mon Sep 17 00:00:00 2001 From: Aleksandra Bozek Date: Wed, 6 Aug 2025 10:57:07 +0200 Subject: [PATCH 3/3] Relocated picker re-positioning logic --- .../public/js/scripts/admin.picker.js | 31 ------------------- .../js/scripts/core/date.time.picker.js | 31 +++++++++++++++++++ 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/src/bundle/Resources/public/js/scripts/admin.picker.js b/src/bundle/Resources/public/js/scripts/admin.picker.js index 669adcc664..6e449d44f0 100644 --- a/src/bundle/Resources/public/js/scripts/admin.picker.js +++ b/src/bundle/Resources/public/js/scripts/admin.picker.js @@ -2,43 +2,12 @@ const SELECTOR_PICKER = '.ibexa-picker'; const SELECTOR_PICKER_INPUT = '.ibexa-date-time-picker__input'; const SELECTOR_FORM_INPUT = '.ibexa-picker__form-input'; - const SECTION_ADJUSTMENT = 24; - const PICKER_ADJUSTMENT = 2; const pickers = doc.querySelectorAll(SELECTOR_PICKER); const { formatShortDateTime, convertDateToTimezone, getBrowserTimezone } = ibexa.helpers.timezone; const userTimezone = ibexa.adminUiConfig.timezone; const pickerConfig = { enableTime: true, time_24hr: true, - onOpen: (selectedDates, dateStr, instance) => { - instance.scrollHandler = () => { - if (instance.isOpen) { - const { calendarContainer, input } = instance; - const rect = input.getBoundingClientRect(); - const pickerHeight = calendarContainer.offsetHeight; - const spaceBelow = global.innerHeight - (rect.bottom + SECTION_ADJUSTMENT); - - if (pickerHeight > spaceBelow) { - calendarContainer.style.top = `${rect.top + global.scrollY - pickerHeight - PICKER_ADJUSTMENT}px`; - calendarContainer.classList.remove('arrowTop'); - calendarContainer.classList.add('arrowBottom'); - } else { - calendarContainer.style.top = `${rect.bottom + global.scrollY + PICKER_ADJUSTMENT}px`; - calendarContainer.classList.remove('arrowBottom'); - calendarContainer.classList.add('arrowTop'); - } - } - }; - - global.addEventListener('scroll', instance.scrollHandler, true); - doc.addEventListener('scroll', instance.scrollHandler, true); - - instance.scrollHandler(); - }, - onClose: (selectedDates, dateStr, instance) => { - global.removeEventListener('scroll', instance.scrollHandler, true); - doc.removeEventListener('scroll', instance.scrollHandler, true); - }, formatDate: (date) => formatShortDateTime(date, null), }; const updateInputValue = (formInput, timestamp) => { diff --git a/src/bundle/Resources/public/js/scripts/core/date.time.picker.js b/src/bundle/Resources/public/js/scripts/core/date.time.picker.js index c05b7c936b..660e8ace07 100644 --- a/src/bundle/Resources/public/js/scripts/core/date.time.picker.js +++ b/src/bundle/Resources/public/js/scripts/core/date.time.picker.js @@ -4,10 +4,41 @@ import { setInstance } from '../helpers/object.instances'; const { ibexa } = window; +const SECTION_ADJUSTMENT = 24; +const PICKER_ADJUSTMENT = 2; const DEFAULT_CONFIG = { enableTime: true, time_24hr: true, formatDate: (date) => formatShortDateTime(date, null), + onOpen: (selectedDates, dateStr, instance) => { + instance.scrollHandler = () => { + if (instance.isOpen) { + const { calendarContainer, input } = instance; + const rect = input.getBoundingClientRect(); + const pickerHeight = calendarContainer.offsetHeight; + const spaceBelow = global.innerHeight - (rect.bottom + SECTION_ADJUSTMENT); + + if (pickerHeight > spaceBelow) { + calendarContainer.style.top = `${rect.top + global.scrollY - pickerHeight - PICKER_ADJUSTMENT}px`; + calendarContainer.classList.remove('arrowTop'); + calendarContainer.classList.add('arrowBottom'); + } else { + calendarContainer.style.top = `${rect.bottom + global.scrollY + PICKER_ADJUSTMENT}px`; + calendarContainer.classList.remove('arrowBottom'); + calendarContainer.classList.add('arrowTop'); + } + } + }; + + window.addEventListener('scroll', instance.scrollHandler, true); + document.addEventListener('scroll', instance.scrollHandler, true); + + instance.scrollHandler(); + }, + onClose: (selectedDates, dateStr, instance) => { + window.removeEventListener('scroll', instance.scrollHandler, true); + document.removeEventListener('scroll', instance.scrollHandler, true); + }, }; class DateTimePicker {