From 9b53a18dd3905c7d25701822cc5ae31c8c2e563c Mon Sep 17 00:00:00 2001 From: Yury Uvarov Date: Mon, 16 Dec 2024 16:44:11 +0300 Subject: [PATCH 1/4] fix display of invalid months --- demo/pages/lang/main.ts | 18 ++++++++++-------- package/src/scripts/creators/createMonths.ts | 15 +++++---------- package/src/scripts/creators/createYears.ts | 2 +- package/src/scripts/utils/getColumnID.ts | 10 ++++++++++ 4 files changed, 26 insertions(+), 19 deletions(-) create mode 100644 package/src/scripts/utils/getColumnID.ts diff --git a/demo/pages/lang/main.ts b/demo/pages/lang/main.ts index 860f5e80..09e11e18 100644 --- a/demo/pages/lang/main.ts +++ b/demo/pages/lang/main.ts @@ -7,10 +7,12 @@ const options: Options = { selectionDatesMode: 'multiple-ranged', disableDatesGaps: true, // disableDatesPast: true, + dateMin: '2021-01-01', + dateMax: '2025-12-31', displayDatesOutside: false, selectionTimeMode: 12, - selectedMonth: 5, - selectedYear: 2024, + selectedMonth: 11, + selectedYear: 2025, timeMinHour: 2, timeMaxHour: 20, timeMinMinute: 10, @@ -63,12 +65,12 @@ const options: Options = { }; document.addEventListener('DOMContentLoaded', () => { - const calendar = new Calendar('#calendar'); + const calendar = new Calendar('#calendar', options); calendar.init(); - const btnSetEl = document.querySelector('#set-options'); - btnSetEl?.addEventListener('click', () => { - calendar.set(options, { dates: false }); - console.log(calendar); - }); + // const btnSetEl = document.querySelector('#set-options'); + // btnSetEl?.addEventListener('click', () => { + // calendar.set(options, { dates: false }); + // console.log(calendar); + // }); }); diff --git a/package/src/scripts/creators/createMonths.ts b/package/src/scripts/creators/createMonths.ts index b91f7cd0..a42daf3d 100644 --- a/package/src/scripts/creators/createMonths.ts +++ b/package/src/scripts/creators/createMonths.ts @@ -1,17 +1,11 @@ import createLayouts from '@scripts/creators/createLayouts'; import setMonthOrYearModifier from '@scripts/creators/setMonthOrYearModifier'; import visibilityTitle from '@scripts/creators/visibilityTitle'; +import getColumnID from '@scripts/utils/getColumnID'; import getDate from '@scripts/utils/getDate'; import setContext from '@scripts/utils/setContext'; import type { Calendar } from '@src/index'; -const relationshipID = (self: Calendar) => { - if (self.type !== 'multiple') return 0; - const columnEls = self.context.mainElement.querySelectorAll('[data-vc="column"]'); - const indexColumn = Array.from(columnEls).findIndex((column) => column.closest('[data-vc-column="month"]')); - return indexColumn > 0 ? indexColumn : 0; -}; - const createMonthEl = ( self: Calendar, templateEl: HTMLButtonElement, @@ -62,8 +56,9 @@ const createMonths = (self: Calendar, target?: HTMLElement) => { const dateMax = getDate(self.context.dateMax); const monthDisabled = - (i < dateMin.getMonth() + relationshipID(self) && selectedYear <= dateMin.getFullYear()) || - (i > dateMax.getMonth() + relationshipID(self) && selectedYear >= dateMax.getFullYear()) || + (selectedYear <= dateMin.getFullYear() && i < dateMin.getMonth() + getColumnID(self)) || + (selectedYear >= dateMax.getFullYear() && i > dateMax.getMonth()) || + selectedYear > dateMax.getFullYear() || (i !== selectedMonth && !activeMonthsID.includes(i)); const monthEl = createMonthEl( self, @@ -78,7 +73,7 @@ const createMonths = (self: Calendar, target?: HTMLElement) => { if (self.onCreateMonthEls) self.onCreateMonthEls(self, monthEl); } - self.context.mainElement.querySelector(`[data-vc-months-month]`)?.focus(); + self.context.mainElement.querySelector(`[data-vc-months-month]:not([disabled])`)?.focus(); }; export default createMonths; diff --git a/package/src/scripts/creators/createYears.ts b/package/src/scripts/creators/createYears.ts index 1037d010..dad7bbc7 100644 --- a/package/src/scripts/creators/createYears.ts +++ b/package/src/scripts/creators/createYears.ts @@ -43,7 +43,7 @@ const createYears = (self: Calendar, target?: HTMLElement) => { if (self.onCreateYearEls) self.onCreateYearEls(self, yearEl); } - self.context.mainElement.querySelector(`[data-vc-years-year]`)?.focus(); + self.context.mainElement.querySelector(`[data-vc-years-year]:not([disabled])`)?.focus(); }; export default createYears; diff --git a/package/src/scripts/utils/getColumnID.ts b/package/src/scripts/utils/getColumnID.ts new file mode 100644 index 00000000..1a6f57f4 --- /dev/null +++ b/package/src/scripts/utils/getColumnID.ts @@ -0,0 +1,10 @@ +import type { Calendar } from '@src/index'; + +const getColumnID = (self: Calendar) => { + if (self.type !== 'multiple') return 0; + const columnEls = self.context.mainElement.querySelectorAll('[data-vc="column"]'); + const indexColumn = Array.from(columnEls).findIndex((column) => column.closest('[data-vc-column="month"]')); + return indexColumn > 0 ? indexColumn : 0; +}; + +export default getColumnID; From 7332f7d952c3eb1e00caa6f4fcff78d6fe22b316 Mon Sep 17 00:00:00 2001 From: Yury Uvarov Date: Mon, 16 Dec 2024 17:10:48 +0300 Subject: [PATCH 2/4] update createMonths.ts and visibilityArrows.ts --- package/src/scripts/creators/createMonths.ts | 2 +- package/src/scripts/creators/visibilityArrows.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package/src/scripts/creators/createMonths.ts b/package/src/scripts/creators/createMonths.ts index a42daf3d..e4122217 100644 --- a/package/src/scripts/creators/createMonths.ts +++ b/package/src/scripts/creators/createMonths.ts @@ -57,7 +57,7 @@ const createMonths = (self: Calendar, target?: HTMLElement) => { const monthDisabled = (selectedYear <= dateMin.getFullYear() && i < dateMin.getMonth() + getColumnID(self)) || - (selectedYear >= dateMax.getFullYear() && i > dateMax.getMonth()) || + (selectedYear >= dateMax.getFullYear() && i > dateMax.getMonth() - (self.context.displayMonthsCount - 1) + getColumnID(self)) || selectedYear > dateMax.getFullYear() || (i !== selectedMonth && !activeMonthsID.includes(i)); const monthEl = createMonthEl( diff --git a/package/src/scripts/creators/visibilityArrows.ts b/package/src/scripts/creators/visibilityArrows.ts index 4dd7bc50..c57b5854 100644 --- a/package/src/scripts/creators/visibilityArrows.ts +++ b/package/src/scripts/creators/visibilityArrows.ts @@ -29,7 +29,7 @@ const handleDefaultType = (self: Calendar, arrowPrevEl: HTMLElement, arrowNextEl const isArrowNextHidden = !self.selectionMonthsMode || jumpDateMax.getFullYear() > dateMax.getFullYear() || - (jumpDateMax.getFullYear() === dateMax.getFullYear() && jumpDateMax.getMonth() > dateMax.getMonth()); + (jumpDateMax.getFullYear() === dateMax.getFullYear() && jumpDateMax.getMonth() > dateMax.getMonth() - (self.context.displayMonthsCount - 1)); setVisibilityArrows(arrowPrevEl, arrowNextEl, isArrowPrevHidden, isArrowNextHidden); }; From 5f5d52ff2f1140a68ecbac3eb2f213b2ee74f386 Mon Sep 17 00:00:00 2001 From: Yury Uvarov Date: Tue, 17 Dec 2024 12:45:52 +0300 Subject: [PATCH 3/4] update main.ts, createMonths.ts, handleClickMonthOrYear.ts and getColumnID.ts --- demo/pages/lang/main.ts | 6 +-- package/src/scripts/creators/createMonths.ts | 6 ++- .../handleClick/handleClickMonthOrYear.ts | 38 ++++++++----------- package/src/scripts/utils/getColumnID.ts | 13 +++++-- 4 files changed, 32 insertions(+), 31 deletions(-) diff --git a/demo/pages/lang/main.ts b/demo/pages/lang/main.ts index 09e11e18..0d7400f6 100644 --- a/demo/pages/lang/main.ts +++ b/demo/pages/lang/main.ts @@ -7,11 +7,11 @@ const options: Options = { selectionDatesMode: 'multiple-ranged', disableDatesGaps: true, // disableDatesPast: true, - dateMin: '2021-01-01', - dateMax: '2025-12-31', + dateMin: '2021-02-01', + dateMax: '2025-11-30', displayDatesOutside: false, selectionTimeMode: 12, - selectedMonth: 11, + selectedMonth: 9, selectedYear: 2025, timeMinHour: 2, timeMaxHour: 20, diff --git a/package/src/scripts/creators/createMonths.ts b/package/src/scripts/creators/createMonths.ts index e4122217..01b8db80 100644 --- a/package/src/scripts/creators/createMonths.ts +++ b/package/src/scripts/creators/createMonths.ts @@ -54,10 +54,12 @@ const createMonths = (self: Calendar, target?: HTMLElement) => { for (let i = 0; i < 12; i++) { const dateMin = getDate(self.context.dateMin); const dateMax = getDate(self.context.dateMax); + const monthCount = self.context.displayMonthsCount - 1; + const { columnID } = getColumnID(self, 'month'); const monthDisabled = - (selectedYear <= dateMin.getFullYear() && i < dateMin.getMonth() + getColumnID(self)) || - (selectedYear >= dateMax.getFullYear() && i > dateMax.getMonth() - (self.context.displayMonthsCount - 1) + getColumnID(self)) || + (selectedYear <= dateMin.getFullYear() && i < dateMin.getMonth() + columnID) || + (selectedYear >= dateMax.getFullYear() && i > dateMax.getMonth() - monthCount + columnID) || selectedYear > dateMax.getFullYear() || (i !== selectedMonth && !activeMonthsID.includes(i)); const monthEl = createMonthEl( diff --git a/package/src/scripts/handles/handleClick/handleClickMonthOrYear.ts b/package/src/scripts/handles/handleClick/handleClickMonthOrYear.ts index fcc32df5..7a5d803f 100644 --- a/package/src/scripts/handles/handleClick/handleClickMonthOrYear.ts +++ b/package/src/scripts/handles/handleClick/handleClickMonthOrYear.ts @@ -2,50 +2,44 @@ import create from '@scripts/creators/create'; import createMonths from '@scripts/creators/createMonths'; import createYears from '@scripts/creators/createYears'; import setMonthOrYearModifier from '@scripts/creators/setMonthOrYearModifier'; +import getColumnID from '@scripts/utils/getColumnID'; import getDate from '@scripts/utils/getDate'; import setContext from '@scripts/utils/setContext'; import type { Calendar, Range } from '@src/index'; const typeClick = ['month', 'year'] as const; -const getColumnID = (self: Calendar, type: (typeof typeClick)[number], id: number) => { - const columnEls: NodeListOf = self.context.mainElement.querySelectorAll('[data-vc="column"]'); - const indexColumn = Array.from(columnEls).findIndex((column) => column.closest(`[data-vc-column="${type}"]`)); - const currentValue = Number((columnEls[indexColumn].querySelector(`[data-vc="${type}"]`) as HTMLElement).getAttribute(`data-vc-${type}`)); +const getValue = (self: Calendar, type: (typeof typeClick)[number], id: number) => { + const { currentValue, columnID } = getColumnID(self, type); - return self.context.currentType === 'month' && indexColumn >= 0 - ? id - indexColumn - : self.context.currentType === 'year' && self.context.selectedYear !== currentValue - ? id - 1 - : id; + if (self.context.currentType === 'month' && columnID >= 0) return id - columnID; + if (self.context.currentType === 'year' && self.context.selectedYear !== currentValue) return id - 1; + return id; }; const handleMultipleYearSelection = (self: Calendar, itemEl: HTMLElement) => { - const selectedYear = getColumnID(self, 'year', Number(itemEl.dataset.vcYearsYear)); + const selectedYear = getValue(self, 'year', Number(itemEl.dataset.vcYearsYear)); const dateMin = getDate(self.context.dateMin); const dateMax = getDate(self.context.dateMax); + const monthCount = self.context.displayMonthsCount - 1; const isBeforeMinDate = self.context.selectedMonth < dateMin.getMonth() && selectedYear <= dateMin.getFullYear(); - const isAfterMaxDate = self.context.selectedMonth > dateMax.getMonth() && selectedYear >= dateMax.getFullYear(); + const isAfterMaxDate = self.context.selectedMonth > dateMax.getMonth() - monthCount && selectedYear >= dateMax.getFullYear(); const isBeforeMinYear = selectedYear < dateMin.getFullYear(); const isAfterMaxYear = selectedYear > dateMax.getFullYear(); - setContext( - self, - 'selectedYear', - isBeforeMinDate || isBeforeMinYear ? dateMin.getFullYear() : isAfterMaxDate || isAfterMaxYear ? dateMax.getFullYear() : selectedYear, - ); - setContext( - self, - 'selectedMonth', - (isBeforeMinDate || isBeforeMinYear ? dateMin.getMonth() : isAfterMaxDate || isAfterMaxYear ? dateMax.getMonth() : self.context.selectedMonth) as Range<12>, - ); + const newSelectedYear = isBeforeMinDate || isBeforeMinYear ? dateMin.getFullYear() : isAfterMaxDate || isAfterMaxYear ? dateMax.getFullYear() : selectedYear; + const newSelectedMonth = + isBeforeMinDate || isBeforeMinYear ? dateMin.getMonth() : isAfterMaxDate || isAfterMaxYear ? dateMax.getMonth() - monthCount : self.context.selectedMonth; + + setContext(self, 'selectedYear', newSelectedYear); + setContext(self, 'selectedMonth', newSelectedMonth as Range<12>); }; const handleMultipleMonthSelection = (self: Calendar, itemEl: HTMLElement) => { const column = itemEl.closest('[data-vc-column="month"]') as HTMLElement; const yearEl = column.querySelector('[data-vc="year"]') as HTMLElement; - const selectedMonth = getColumnID(self, 'month', Number(itemEl.dataset.vcMonthsMonth)); + const selectedMonth = getValue(self, 'month', Number(itemEl.dataset.vcMonthsMonth)); const selectedYear = Number(yearEl.dataset.vcYear); const dateMin = getDate(self.context.dateMin); const dateMax = getDate(self.context.dateMax); diff --git a/package/src/scripts/utils/getColumnID.ts b/package/src/scripts/utils/getColumnID.ts index 1a6f57f4..7602233d 100644 --- a/package/src/scripts/utils/getColumnID.ts +++ b/package/src/scripts/utils/getColumnID.ts @@ -1,10 +1,15 @@ import type { Calendar } from '@src/index'; -const getColumnID = (self: Calendar) => { - if (self.type !== 'multiple') return 0; +const getColumnID = (self: Calendar, type: string) => { + if (self.type !== 'multiple') return { currentValue: null, columnID: 0 }; + const columnEls = self.context.mainElement.querySelectorAll('[data-vc="column"]'); - const indexColumn = Array.from(columnEls).findIndex((column) => column.closest('[data-vc-column="month"]')); - return indexColumn > 0 ? indexColumn : 0; + const columnID = Array.from(columnEls).findIndex((col) => col.closest(`[data-vc-column="${type}"]`)); + + return { + currentValue: columnID >= 0 ? Number(columnEls[columnID].querySelector(`[data-vc="${type}"]`)?.getAttribute(`data-vc-${type}`)) : null, + columnID: Math.max(columnID, 0), + }; }; export default getColumnID; From 5178a93f738dc13553e0db93baecb8147c38a8eb Mon Sep 17 00:00:00 2001 From: Yury Uvarov Date: Tue, 17 Dec 2024 12:53:00 +0300 Subject: [PATCH 4/4] update handleClickMonthOrYear.ts --- .../handles/handleClick/handleClickMonthOrYear.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/package/src/scripts/handles/handleClick/handleClickMonthOrYear.ts b/package/src/scripts/handles/handleClick/handleClickMonthOrYear.ts index 7a5d803f..ee9e5f90 100644 --- a/package/src/scripts/handles/handleClick/handleClickMonthOrYear.ts +++ b/package/src/scripts/handles/handleClick/handleClickMonthOrYear.ts @@ -22,15 +22,20 @@ const handleMultipleYearSelection = (self: Calendar, itemEl: HTMLElement) => { const dateMin = getDate(self.context.dateMin); const dateMax = getDate(self.context.dateMax); const monthCount = self.context.displayMonthsCount - 1; + const { columnID } = getColumnID(self, 'year'); const isBeforeMinDate = self.context.selectedMonth < dateMin.getMonth() && selectedYear <= dateMin.getFullYear(); - const isAfterMaxDate = self.context.selectedMonth > dateMax.getMonth() - monthCount && selectedYear >= dateMax.getFullYear(); + const isAfterMaxDate = self.context.selectedMonth > dateMax.getMonth() - monthCount + columnID && selectedYear >= dateMax.getFullYear(); const isBeforeMinYear = selectedYear < dateMin.getFullYear(); const isAfterMaxYear = selectedYear > dateMax.getFullYear(); const newSelectedYear = isBeforeMinDate || isBeforeMinYear ? dateMin.getFullYear() : isAfterMaxDate || isAfterMaxYear ? dateMax.getFullYear() : selectedYear; const newSelectedMonth = - isBeforeMinDate || isBeforeMinYear ? dateMin.getMonth() : isAfterMaxDate || isAfterMaxYear ? dateMax.getMonth() - monthCount : self.context.selectedMonth; + isBeforeMinDate || isBeforeMinYear + ? dateMin.getMonth() + : isAfterMaxDate || isAfterMaxYear + ? dateMax.getMonth() - monthCount + columnID + : self.context.selectedMonth; setContext(self, 'selectedYear', newSelectedYear); setContext(self, 'selectedMonth', newSelectedMonth as Range<12>);