์ด์ ์ฑํฐ์์ shift Month Button๋ฅผ ํตํด ์ด์ ๊ณผ ๋ค์ ๋ฌ๋ก ์ด๋ํ ์ ์๊ฒ ๋์์ต๋๋ค. ๊ทธ๋ ๋ค๋ฉด ๋ค์๊ณผ ๊ฐ์ ๊ฒฝ์ฐ์ ์ด๋ป๊ฒ ํด์ผ ํ ๊น์?
์ค๋์ด 2023๋ 10์ 31์ผ์ธ๋ฐ 2020๋ 10์์ ๋ฌ๋ ฅ์ ๋ณด๊ณ ์ถ๋ค.
๋ฒํผ์ 36๋ฒ ํด๋ฆญํ์ฌ 3๋ ์ ์ผ๋ก ์ด๋ํด์ผ ํฉ๋๋ค. ๋๋ฌด๋ ๋ง์ ๋ฒํผ ํด๋ฆญ์ ๋๋ค. ์ฌ์ฉ์ฑ๋ ๋ง์ด ๋จ์ด์ง๋๋ค. ์ฌ์ฉ์๋ ๊ฐ๋จํ๊ฒ ์์ ์ด ์ํ๋ ๋ (year), ์(month)๋ก ์ด๋ํ๋ ๊ฒ์ ๋ฐ๋ผ๊ณ ์์ต๋๋ค. ์ด๋ฅผ ์ด๋ฒ ์ฑํฐ์์ Navigation ๊ธฐ๋ฅ์ ์ถ๊ฐํ๋ฉด์ ํด๊ฒฐํฉ๋๋ค.
1. Calendar class์ ๊ธฐ๋ฅ ์ถ๊ฐํ๊ธฐ
์ด์ ์ฑํฐ์์๋ shiftMonth ๋ฉ์๋๋ฅผ ์ถ๊ฐํ์ฌ ์(month)์ ์ด๋ํ ์ ์๊ฒ ํ์ต๋๋ค. ํ์ง๋ง ๋งค๊ฐ๋ณ์๋ก next, prev, today๋ฅผ ๋ฐ๊ธฐ ๋๋ฌธ์ ํน์ ์๋ก ์ด๋ํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด 1์์์ 10์๋ก ํ ๋ฒ์ ์ด๋ํ ์ ์์ต๋๋ค. ์ด๋ป๊ฒ ํด๊ฒฐํ ์ ์์๊น์? navigation ๊ธฐ๋ฅ์ ์ถ๊ฐํ๋ฉด ๋ฉ๋๋ค.
navigation ๊ธฐ๋ฅ์ ํน์ ๋ (year), ์(month)๋ก ์ด๋ํ ์ ์๋ ๊ธฐ๋ฅ์ด๋ผ๊ณ ์๊ฐํ๋ฉด ๋ฉ๋๋ค. ๊ธ๋ก๋ง ์ค๋ช ํ๋ ๋ถ์กฑํ ๋๋์ด ๋ญ๋๋ค. ์ค์ ์ฌ์ง์ ๋ณด๋ฉด์ ์ค๋ช ์ ๋๋ฆฌ๊ฒ ์ต๋๋ค.
์ ์ฌ์ง์์ ๋นจ๊ฐ์ ์ ์ผ๋ก ๋๋ฌ์ผ ๋ถ๋ถ์ด Calendar์ navigation์ ๋๋ค. ํ์ดํ๋ฅผ ์ฌ์ฉํ์ฌ ๋น ๋ฅด๊ฒ ์ฐ๋(year)๋ฅผ ๋ณ๊ฒฝํ ์ ์๊ณ 1์๋ถํฐ 12์๊น์ง ์ํ๋ ์(month)์ ํ ๋ฒ์ ํด๋ฆญ์ผ๋ก ๋ณ๊ฒฝํ ์ ์์ต๋๋ค.
์ด์ ๊ฐ์ ๊ธฐ๋ฅ์ ์ถ๊ฐํ๊ธฐ ์ํด Calendar class์ ๋ณ์์ ๋ฉ์๋๋ฅผ ์ถ๊ฐํ๊ณ ๊ธฐ์กด ๋ฉ์๋์ ๊ธฐ๋ฅ์ ์ถ๊ฐ ํด๋ณด๋๋ก ํฉ์๋ค.
1-1. #navigationYear, #navigationMonth ์ถ๊ฐ
// Calendar.ts
class Calendar {
// ...
#navigationYear;
#navigationMonth;
// ...
constructor(year: number, month: number) {
this.#year = year;
this.#month = month;
this.#navigationYear = year;
this.#navigationMonth = month;
}
}
navigation์ ํ์ํ private filed์ธ #navigationYear, #navigationMonth๋ฅผ ์ถ๊ฐํฉ๋๋ค. ์ด ๋ณ์๋ ์์ผ๋ก ๋ณ๊ฒฝํ๊ฒ ๋ ์ค์ ๋ (year), ์(month)๊ฐ ๋ฉ๋๋ค.
์ ๋ฐ๋ก ๋ณ์๋ฅผ ๋ง๋ค๊ณ ์ ์ฅ์ ํ ๋ค, ๋์ค์ ์ ์ฉ์ ํ๋๊ฑธ๊น์? ๋ง์ฝ navigation์ ๋ (year)์ด ๊ณ์ ๋ณ๊ฒฝ๋ ๋๋ง๋ค ๋ค์ ๋ฌ๋ ฅ์ด ๋ฐ๋๊ฒ ๋๋ค๋ฉด ๊น๋ํ ๋๋์ UI์ด ์ฌ๋ผ์ง๊ณ ์ด์ง๋ฌ์ด ๋๋์ด ๋ค ์ ์๋ค๊ณ ์๊ฐํ๊ธฐ ๋๋ฌธ์ ๋๋ค. ๊ทธ๋์ ์ ๋ ์ฌ์ฉ์๊ฐ ์ํ๋ ๋ (year), ์(month)์ ์ ํํ๊ฒ ๋๋ฉด ๊ทธ๋, ํ ๋ฒ ๋ฌ๋ ฅ์ด ๋ณ๊ฒฝ๋ ์ ์๋๋ก ํ์ต๋๋ค. ๋ง์ฝ ์ด ๋ถ๋ถ์ ๋ํด์ ๋ค๋ฅธ ์๊ฐ์ ๊ฐ์ง๊ณ ์๋ค๋ฉด ์ํ๋ ๊ฒฐ๊ณผ๊ฐ ๋ํ๋๋๋ก ๋ก์ง์ ์์ ํ์๋ฉด ๋ฉ๋๋ค. ์ด๋ฐ ๊ฒฝ์ฐ ๊ธฐ์กด shiftMonth ๋ฉ์๋๋ง ์กฐ๊ธ ์์ ํ๋ฉด ๋ ์์ํ๊ฒ navigation ๊ธฐ๋ฅ์ ์ถ๊ฐํ ์ ์๊ฒ ๋ค์.
1-2. ๋ฉ์๋ ์ถ๊ฐํ๊ธฐ
navigation์ ํ์ํ ์ฌ๋ฌ ๋ฉ์๋๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ์ถ๊ฐํฉ๋๋ค.
// Calendar.ts
class Calendar {
// ...
navigateYear = (year: number) => (this.#navigationYear = year);
navigateMonth = (month: number) => (this.#navigationMonth = month);
navigate = () => {
this.#year = this.#navigationYear;
this.#month = this.#navigationMonth;
};
getNavigationYear = () => this.#navigationYear;
getNavigationMonth = () => this.#navigationMonth;
// ...
}
์ฌ๋ฌ ๋ฉ์๋๋ค์ด ์ถ๊ฐ๋์๋๋ฐ, ํ๋์ฉ ์ดํด๋ณด๋ฉด ์ด๋ ต์ง ์๋ ๋ก์ง์ผ๋ก ์ด๋ฃจ์ด์ ธ ์์ต๋๋ค.
๋จผ์ navigateYear ๋ฉ์๋์ navigateMonth ๋ฉ์๋์ ๋๋ค. ์ด ๋ ๋ฉ์๋๋ ๊ฐ๊ฐ ๋ณ์ #navigationYear๊ณผ #navigationMonth๋ฅผ ๋ณ๊ฒฝํ๋ ์ญํ ์ ํฉ๋๋ค.
๋ค์์ navigate ๋ฉ์๋์ ๋๋ค. ์ด ๋ฉ์๋๋ฅผ ํธ์ถํ๊ฒ ๋๋ฉด ๋ฌ๋ ฅ์ ๋ (year)๊ณผ ์(month)์ด ์ ๋ฐ์ดํธ๋ฉ๋๋ค.
๋ง์ง๋ง์ getNavigationYear ๋ฉ์๋์ getNavigationMonth ๋ฉ์๋์ ๋๋ค. ์ด๋ ๋ณ์ #navigationYear๊ณผ #navigationMonth์ ๊ฐ์ ๋ฐํํ๋ ์ญํ ์ ํฉ๋๋ค.
1-3. shiftMonth ๋ฉ์๋์ ๊ธฐ๋ฅ ์ถ๊ฐํ๊ธฐ
shiftMonth ๋ฉ์๋๋ ๋ฌ๋ ฅ์ ์์ ์ด๋ํ ๋ ์ฌ์ฉํ๋ ๋ฉ์๋์ ๋๋ค. ์ด๋ฌํ ๋ฉ์๋์ ๋ค์๊ณผ ๊ฐ์ ๊ธฐ๋ฅ์ ์ถ๊ฐํ ๊ฒ์ ๋๋ค.
1. #month๊ฐ ๋ณ๊ฒฝ๋๋ฉด #navigationMonth๋ ํจ๊ป ๋ณ๊ฒฝ๋๋ค.
2. #year๊ฐ ๋ณ๊ฒฝ๋๋ฉด #navigationYear๋ ํจ๊ป ๋ณ๊ฒฝ๋๋ค.
์ด๋ฌํ ์ด์ ๋ ์๋์ ์ํฉ์ ์๊ฐํด ๋ณด๋ฉด ๋ฉ๋๋ค.
ํ์ฌ ๋ด๊ฐ ๋ณด๊ณ ์๋ ๋ฌ๋ ฅ์ 2024๋ 1์์ธ๋ฐ, ๋ด๋น๊ฒ์ด์ ์ ํ๊ธฐ ์ํด ๋ค์ด๊ฒ์ด์ UI๋ฅผ ์ด์ด ๋ดค๋๋ 2023๋ ์ด ๋ํ๋๋ค
์ด์ํฉ๋๋ค. ํ์ฌ ๋ด๊ฐ ์๋ ๋ ๋(year)(์ ์์์์๋ 2024๋ )์์๋ถํฐ ๋ค์ด๊ฒ์ด์ ์ ์์ํ๊ณ ์ถ์ต๋๋ค. ์์ ๊ฐ์ ์ํฉํฉ์ด ๋ํ๋์ง ์๋๋ก shiftMonth ๋ฉ์๋์ ๋ค์๊ณผ ๊ฐ์ด ๋ก์ง์ ์ถ๊ฐํ๊ณ ๋ฆฌํฉํฐ๋ง ํฉ๋๋ค.
shiftMonth = (type: 'next' | 'prev' | 'today') => {
let newYear = this.#year;
let newMonth = this.#month;
if (type === 'today') {
const today = new Date();
newYear = today.getFullYear();
newMonth = today.getMonth() + 1;
}
const changedMonth = this.#month + (type === 'next' ? +1 : -1);
if (type !== 'today' && changedMonth === 0) {
newYear -= 1;
newMonth = 12;
}
if (type !== 'today' && changedMonth === 13) {
newYear += 1;
newMonth = 1;
}
if (type !== 'today' && changedMonth > 0 && changedMonth < 13) {
newMonth = changedMonth;
}
this.#year = newYear;
this.#navigationYear = newYear;
this.#month = newMonth;
this.#navigationMonth = newMonth;
};
newYear, newMonth ๋ณ์๋ฅผ ๋ง๋ค์์ต๋๋ค. ์ดํ type๊ณผ changedMonth์ ๋ฐ๋ผ newYear, newMonth์ ์๋ก์ด ๊ฐ์ ํ ๋นํฉ๋๋ค.
๋ชจ๋ ์ฐ์ฐ์ด ๋ง๋ฌด๋ฆฌ๋๋ฉด #year, #navigationYear์ newYear ๊ฐ์ ํ ๋นํ๊ณ #month, #navigationMonth์ newMonth ๊ฐ์ ํ ๋นํฉ๋๋ค.
1-4. ๋ง๋ฌด๋ฆฌ
navigation ๊ธฐ๋ฅ์ ์ถ๊ฐํ๊ธฐ ์ํด Calendar class์ ์๋ก์ด ๋ณ์์ ๋ฉ์๋๋ฅผ ์ถ๊ฐํ์ต๋๋ค. ๋ํ ๊ธฐ์กด shiftMonth ๋ฉ์๋๋ ์์ ํ์ต๋๋ค. ๋ค์์ ์ด๋ฒ ์์ ์ ๋ํ commit์ ๋๋ค.
2. Schedule์์ Navigation ํ๊ธฐ
์ค์ Navigation ๊ธฐ๋ฅ์ Schedule ๋ฌ๋ ฅ์ ์ถ๊ฐํด ๋ด ์๋ค. UI๋ถํฐ ์๊ฐ์ ํด๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ์ ๊ฒ๋ค์ด ํ์ํฉ๋๋ค.(์ดํด๋ฅผ ์ํด ํ๋ฃจ์คํฐ๋์ UI์ ํจ๊ป ์ค๋ช ํฉ๋๋ค.)
1. navigation ๋ฌ๋ ฅ: ์๋์ ์ฌ์ง์์ ๋นจ๊ฐ์ ์ฌ๊ฐํ์ธ ๋ถ๋ถ์ผ๋ก ์(month)๊น์ง ๋์ค๋ ๋ฌ๋ ฅ์ ๋๋ค.
2. navigation ๋ฌ๋ ฅ์ ์ด๊ณ ๋ซ๋ ๋ฒํผ: ๋ฒํผ(์ด๋ก์ ์) ํด๋ฆญ ํตํด navigation ๋ฌ๋ ฅ์ ์ด๊ณ ๋ซ์ ์ ์์ต๋๋ค.
UI๋ฅผ ๋จผ์ ๋ง๋ค๊ณ navigation ๊ธฐ๋ฅ์ ์ถ๊ฐํ๋๋ก ํฉ์๋ค.
2-1. ๋ฒํผ ๋ง๋ค๊ธฐ
์ฐ์ ๋ฒํผ(์ ์ฌ์ง ๊ธฐ์ค ์ด๋ก์ ์)์ ์ถ๊ฐํ๋๋ก ํ๊ฒ ์ต๋๋ค. ์ด๋ฅผ ์ํด์ yearMonthTemplate์ ์์ ํด์ผ ํฉ๋๋ค.
// template/yearMonthTemplate
const yearMonthTemplate = (
calendar: 'schedule' | 'datePicker',
year: number,
month: number
) => `
<div class=${
calendar === 'schedule' ? 'schedule-year-month' : 'date-picker-year-month'
}>
<div>
<span>${year}๋
${month}์</span>
${
calendar === 'schedule' &&
`<button class="schedule-navigation-button">โผ</button>`
}
</div>
<div class="shift-month-button-container">
<button class="shift-month-button shift-mont-today-button" data-type="today">TODAY</button>
<button class="shift-month-button shift-mont-arrow-button" data-type="prev">โ๏ธ</button>
<button class="shift-month-button shift-mont-arrow-button" data-type="next">โถ๏ธ</button>
</div>
</div>
`;
export default yearMonthTemplate;
shift-month-button-container๋ ๊ธฐ์กด๊ณผ ๋์ผํฉ๋๋ค.
schedule-navigation-button์ ์ถ๊ฐํ์ฌ ๋ (year), ์(month) ๋ค์์ โผ ๋ฒํผ์ ์์ฑํฉ๋๋ค.
2-2. navigation ๋ฌ๋ ฅ ์ถ๊ฐํ๊ธฐ
์์ ์ดํด๋ณธ ์ฌ์ง์์ ๋นจ๊ฐ์ ์ฌ๊ฐํ ๋ถ๋ถ์ navigation์ ํ ์ ์๋๋ก ๋์์ฃผ๋ ๋ฌ๋ ฅ์ด๋ผ๊ณ ํ์ฌ navigation ๋ฌ๋ ฅ์ด๋ผ๊ณ ํ๊ฒ ์ต๋๋ค.
navigation ๋ฌ๋ ฅ์ ๋ ๋๋ง์ ํ๊ธฐ ์ํด Schedule class์ ๋ฉ์๋๋ฅผ ์ถ๊ฐํฉ๋๋ค.
// Schedule.ts
private renderNavigation = () => {
const navigationYear = this.#calendar.getNavigationYear();
const year = this.#calendar.getYear();
const isScheduleMonth = (month: number) => {
if (navigationYear !== year) return false;
return this.#calendar.getNavigationMonth() === month;
};
const navigationTemplate = `
<div class="schedule-navigation">
<div class="schedule-navigation-year">
<span>${navigationYear}</span>
<div class="schedule-navigation-year-buttons">
<button class="schedule-navigation-year-button" data-type="prev">โ๏ธ</button>
<button class="schedule-navigation-year-button" data-type="next">โถ๏ธ</button>
</div>
</div>
<ul class="schedule-navigation-month-list">
${Array.from({ length: 12 })
.map(
(_, index) =>
`<li class="schedule-navigation-month-item ${
isScheduleMonth(index + 1) ? 'schedule-month' : ''
}" data-month="${index + 1}">${index + 1}์</li>`
)
.join('')}
</ul>
</div>
`;
$('.schedule-year-month').insertAdjacentHTML(
'beforeend',
navigationTemplate
);
this.registerNavigationEventListener();
};
๋ฉ์๋ ์ด๋ฆ์ renderNavigation์ ๋๋ค. ์ด ๋ฉ์๋์ ๋ก์ง์ ๊ฐ๋จํ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
๋จผ์ navigationYear๋ณ์, year๋ณ์์ ๋๋ค. ์ด ๋ณ์๋ค์ isScheduleMonth ํจ์์์ ์๋ก ๋น๊ตํ ๋ ์ฌ์ฉ๋ฉ๋๋ค. navigationYear์ navigationTemplate๋ฅผ ๋ง๋ค ๋์๋ ์ฌ์ฉ๋ฉ๋๋ค.
๋ค์์ isScheduleMonthํจ์์ ๋๋ค. ์ด ํจ์๋ ํ์ฌ ๋จธ๋ฌผ๋ฌ ์๋ ๋ (year), ์(month)์ navigation ๋ฌ๋ ฅ์์ ํ์ธํ ์ ์๋๋ก ๋์์ฃผ๋ ์ญํ ์ ํฉ๋๋ค. ์ฒซ ๋ฒ์งธ๋ก navigationYear๊ณผ year์ด ์๋ก ๊ฐ์์ง ํ์ธํฉ๋๋ค. ์๋ก ๊ฐ์ง ์๋๋ค๋ฉด false๋ฅผ return ํฉ๋๋ค. ๊ทธ๋ค์์ calendar ์ธ์คํด์ค์ getNavigationMonth ๋ฉ์๋๋ฅผ ํตํด ๊ฐ์ ธ์จ navigationMonth๊ฐ ๋งค๊ฐ๋ณ์๋ก ๋ฐ์ month์ ๊ฐ์์ง๋ฅผ ํ๋จํ๊ณ ์ด ๊ฒฐ๊ณผ๋ฅผ return ํฉ๋๋ค.
๋ค์์ navigationTemplate์ ๋๋ค. ์ด๋ ์ค์ ๋ก ํ๋ฉด์ ๋ณด์ฌ์ง๋ UI๋ฅผ ๊ทธ๋ฆฌ๋ ์ญํ ์ ํฉ๋๋ค. UI์ ๋ํ ์คํ์ผ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
/* css/schedule.css */
.schedule-year-month {
position: relative;
padding: 20px 20px 40px;
font-size: 24px;
display: flex;
align-items: center;
justify-content: space-between;
}
.schedule-navigation-button {
font-size: 16px;
background-color: transparent;
border: none;
cursor: pointer;
}
.schedule-navigation {
position: absolute;
top: 50px;
width: 300px;
padding: 20px;
border-radius: 8px;
background-color: #ffffff;
box-shadow: rgba(149, 157, 165, 0.2) 0px 8px 24px;
font-size: 18px;
z-index: 5;
}
.schedule-navigation-year {
display: flex;
justify-content: space-between;
margin-bottom: 20px;
}
.schedule-navigation-year-button {
font-size: 16px;
border: none;
background-color: transparent;
cursor: pointer;
}
.schedule-navigation-month-list {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 10px;
font-size: 16px;
font-weight: 500;
color: rgb(100, 100, 100);
}
.schedule-month {
color: #3b82f6;
}
.schedule-navigation-month-item {
text-align: center;
padding: 10px 5px;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.2s ease;
}
.schedule-navigation-month-item:hover {
background-color: #d7e6ff;
}
์คํ์ผ ์ฝ๋๊ฐ ๊น๋๋ค. ๊ฐ์์ ๊ธฐํธ์ ๋ง๊ฒ ์์ ํ์ฌ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค. navigationTemplate์ insertAdjacentHTML ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ schedule-year-month์ ๋ง์ง๋ง ์์์ผ๋ก ์ถ๊ฐํฉ๋๋ค.
๋ง์ง๋ง์ registerNavigationEventListener ๋ฉ์๋๋ฅผ ํธ์ถํฉ๋๋ค. ์ด๋ navigation ๊ธฐ๋ฅ์ ์ํ ์ด๋ฒคํธ๋ฅผ ๋ฑ๋กํ๋ ๋ฉ์๋์ด๋ฉฐ ์์ง ๊ตฌํํ์ง ์์์ต๋๋ค. ์ด์ ๋ํด์๋ 2-4์์ ๋ ์์ธํ ์ค๋ช ์ด ์ด์ด์ง๋๋ค.
2-3. navigation ๋ฌ๋ ฅ ์ด๊ณ ๋ซ๊ธฐ
schedule-navigation-button์ ํด๋ฆญํ๋ฉด navigation ๋ฌ๋ ฅ์ด ๋ํ๋๋๋ก ์ด๋ฒคํธ ๋ฆฌ์ค๋๋ฅผ ์ถ๊ฐํด ๋ด ์๋ค. ์ด๋ฅผ ์ํด์ ๊ธฐ์กด registerEventListener์ ์๋ก์ด ์ด๋ฒคํธ๋ฅผ ์ถ๊ฐํด์ผ ํฉ๋๋ค.
private registerEventListener = () => {
// ...
$('.schedule-navigation-button').addEventListener(
'click',
this.handleOpenNavigation
);
};
์ด์ , schedule-navigation-button์ ํด๋ฆญํ๋ฉด handleOpenNavigation ๋ฉ์๋๊ฐ ์คํ๋ฉ๋๋ค. handleOpenNavigation ๋ฉ์๋๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
class Schedule {
#isOpenNavigation = false;
// ...
private handleOpenNavigation = () => {
if (this.#isOpenNavigation) {
this.#isOpenNavigation = false;
$('.schedule-navigation').remove();
return;
}
this.#isOpenNavigation = true;
this.renderNavigation();
};
}
#isOpenNavigation์ด๋ผ๋ private filed์ ๋ง๋ค๊ณ ์ด ๋ณ์์ ์ํ์ ๋ฐ๋ผ ๋ค๋ฅธ ๋ก์ง์ด handleOpenNavigation์์ ์คํ๋ฉ๋๋ค.
#isOpenNavigation์ด true๋ผ๋ฉด ์ด๋ฏธ navigation ๋ฌ๋ ฅ์ด ์ด๋ ค์๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ์ด๋ฅผ ๋ซ๊ธฐ ์ํด remove ๋ฉ์๋๋ฅผ ์ฌ์ฉํฉ๋๋ค. ๋ฐ๋๋ก #isOpenNavigation์ด false๋ผ๋ฉด renderNavigation ๋ฉ์๋๋ฅผ ์คํ์์ผ navigation ๋ฌ๋ ฅ์ ์ฝ๋๋ค.
2-4. navigation ๊ธฐ๋ฅ ์ถ๊ฐํ๊ธฐ
navigation ๊ธฐ๋ฅ์ ๊ตฌํํ๊ธฐ ์ํ ์ค๋น๋จ๊ณ๊ฐ ๋ชจ๋ ๋๋ฌ์ต๋๋ค. ์ด์ ์ํ๋ ๋ (year), ์(month)๋ก ์์ ๋กญ๊ฒ ์ด๋ํ ์ ์๋ navigation ๊ธฐ๋ฅ์ ์ถ๊ฐํ ์ ์์ต๋๋ค.
๋ค์ ์ฌ์ง์ ๋ณด๋ฉด ๋ (year)์ ์ด๋์ํฌ ์ ์๋ ํ์ดํ ๋ฒํผ๊ณผ ์(month)์ ์ ํํ ์ ์๋ 1~12์ ๋ฒํผ์ด ์์ต๋๋ค.
๋๋ฌธ์ ๋ ๊ฐ์ ๊ธฐ๋ฅ์ ์ถ๊ฐํด์ผ ํฉ๋๋ค. ์ ๋ ์ด๋ ๊ฒ ํ๊ณ ์ถ์ต๋๋ค.
1. ๋ (year)์ ์ด๋์ํฌ ์ ์๋ ํ์ดํ๋ฅผ ๋๋ฅด๋ฉด navigation year์ด ๋ณํ๋ค.
2. ์(month)์ ์ ํํ ์ ์๋ 1~12์ ๋ฒํผ์ ๋๋ฅด๋ฉด ํด๋น ์๋ก ์ด๋ํ๊ณ navigation ๋ฌ๋ ฅ์ด ๋ซํ๋ค.
์ด๋ฅผ ์ํด ๋จผ์ ๋ค์๊ณผ ๊ฐ์ด ์ด๋ฒคํธ๋ฅผ ์ถ๊ฐํฉ๋๋ค.
private registerNavigationEventListener = () => {
$('.schedule-navigation-year-buttons').addEventListener('click', (event) =>
this.handleNavigateYear(event)
);
$('.schedule-navigation-month-list').addEventListener('click', (event) =>
this.handleNavigateCalendar(event)
);
};
ํ๋๋ schedule-navigation-year-buttons์ ํด๋ฆญํ ๋ ๋ฐ์ํ๋ ์ด๋ฒคํธ์ด๊ณ ๋ค๋ฅธ ํ๋๋ schedule-navigation-month-list์ ํด๋ฆญํ ๋ ๋ฐ์ํ๋ ์ด๋ฒคํธ์ ๋๋ค. ํ๋์ฉ ์ดํด๋ด ์๋ค.
๋จผ์ handleNavigateYear ๋ฉ์๋์ ๋๋ค.
private handleNavigateYear: EventListener = (event) => {
const button = event.target;
if (!(button instanceof HTMLButtonElement)) return;
const type = button.dataset.type as 'next' | 'prev';
const newNavigationYear =
this.#calendar.getNavigationYear() + (type === 'next' ? +1 : -1);
this.#calendar.navigateYear(newNavigationYear);
$('.schedule-navigation').remove();
this.renderNavigation();
};
์ด ๋ฉ์๋์์๋ button์ ํ์ ์ด next์ธ์ง ์๋๋ฉด prev์ธ์ง ํ์ธํ๊ณ ๊ทธ์ ๋ฐ๋ผ navigationYear์ ๋ณ๊ฒฝ์ํต๋๋ค. ์ดํ schedule-navigation ์ฆ, navigation ๋ฌ๋ ฅ์ ์ ๊ฑฐํ๊ณ renderNavigation ๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ ์๋กญ๊ฒ ๊ทธ๋ฆฝ๋๋ค.
๋ค์์ handleNavigateCalendar ๋ฉ์๋์ ๋๋ค.
private handleNavigateCalendar: EventListener = (event) => {
const monthElement = event.target;
if (!(monthElement instanceof HTMLLIElement)) return;
const month = monthElement.dataset.month as string;
this.#calendar.navigateMonth(Number(month));
this.#calendar.navigate();
$('.schedule-navigation').remove();
this.renderCalendar();
};
์ด ๋ฉ์๋๋ 1~12 ๋ฒํผ์ ํด๋ฆญํ๋ฉด ์คํ๋๋ ๋ฉ์๋์ ๋๋ค. ์ฐ์ ์ซ์์ ํด๋นํ๋ ๊ฐ์ ๊ฐ์ ธ์ month ๋ณ์์ ํ ๋นํฉ๋๋ค. ์ดํ calendar.navigateMonth ๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ navigationMonth๋ฅผ ์ ๋ฐ์ดํธํ๊ณ ์ด์ด์ calendar.navigate ๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ year, month์ ์ ๋ฐ์ดํธํฉ๋๋ค.
์ดํ schedule ๋ฌ๋ ฅ์ ๋ซ๊ณ renderCalendar ๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ ์๋ก์ด ๋ฌ๋ ฅ์ ๊ทธ๋ฆฝ๋๋ค.
2-5. ์ต์ข ๊ฒฐ๊ณผ
์ฑ๊ณต์ ์ผ๋ก navigation ๊ธฐ๋ฅ์ ์ถ๊ฐํ์ต๋๋ค.
๋ค์์ ์ด๋ฒ ์์ ์ ๋ํ commit์ ๋๋ค.
3. Date Picker์์์ navigation?
์ด ๊ธ์์๋ Date Picker์์์ navigation ๊ธฐ๋ฅ์ ๋ค๋ฃจ์ง ์์ต๋๋ค. ํ์ง๋ง ์ด๋ค ์ปจ์ ์ธ์ง๋ง ํ์ธํฉ๋๋ค. Date Picker์์์ navigation ๊ธฐ๋ฅ์ Schedule์์์ navigation ๊ธฐ๋ฅ๊ณผ ์กฐ๊ธ ๋ค๋ฅด๋ค๊ณ ์๊ฐํฉ๋๋ค.
Schedule์์์ navigationYear๊ณผ navigationMonth๋ ํจ๊ป ์ ํ๋์ด ๋ฐ์๋์ง๋ง Date Picker์์๋ ๊ทธ๋ ์ง ์์ต๋๋ค. navigationYear๊ณผ navigationMonth๊ฐ ๊ฐ๊ฐ ์ ํ๋์ด ๋ฌ๋ ฅ์ ๋ฐ์๋๋ ํ์์ด์ฃ .
๋ค์์ ์์์ ํ๋ฃจ์คํฐ๋์์์ Date Picker์ navigation ๊ธฐ๋ฅ์ ๋๋ค. ๋ (year)๊ณผ ์(month)์ ๊ฐ๊ฐ select๋ฅผ ํ ์ ์์ต๋๋ค.
ํ๋ฃจ์คํฐ๋์ Select ์ปดํฌ๋ํธ๊ฐ ์์ต๋๋ค. ์ด๋ฅผ ํ์ฉํ์์ต๋๋ค. ๊ฐ๋จํ๊ฒ ๋ง๋ค๊ธฐ ์ํด์ select tag๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค. ์ปจ์ ์ ๋๋ฅผ ์๊ฐํ๋ ๊ฒ์ ๋์ผ๋ก ์ด๋ฒ ์ฑํฐ๋ฅผ ๋ง๋ฌด๋ฆฌํ๊ฒ ์ต๋๋ค.
4. ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์์ด ์๋ฐ์คํฌ๋ฆฝํธ๋ก ๋ฌ๋ ฅ ๋ง๋ค๊ธฐ๋ฅผ ๋๋ด๋ฉฐ
2๋ ์ , ํฐ์ฒ์บ์์ ๋ฌ๋ ฅ์ ๊ตฌํํ๊ธฐ ์ํด ๋ง์ ๋ ํผ๋ฐ์ค๋ฅผ ์ฐพ์์์ต๋๋ค. ์ด์ฐ์ด์ฐ ์์ฑ์ ํ์ต๋๋ค. ํ์ง๋ง ๊น๋ํ๊ฒ ๋ง๋ค์ง ๋ชปํด ์์ฌ์์ด ๋จ์์์๊ณ ๋ฆฌํฉํฐ๋ง ๋ํ ์ฝ๊ฒ ํ์ง ๋ชปํด ์ธ์ ๊ฐ๋ ํ ๋ฒ ๋ค์ ์ ๋ฆฌ๋ฅผ ํ๊ณ ๋ฌ๋ ฅ์ ๋ง๋ค์ด์ผ๊ฒ ๋ค๊ณ ๋ค์งํ์ต๋๋ค. ์ง์ง ์๋ ์ฝ๋๋ฅผ ๋ณด๋ฉด ๋ฌด์จ ์๊ฐ์ผ๋ก ๋ก์ง์ ์์ฑํ๋์ง ๋ชจ๋ฅด๊ฒ ์ต๋๋ค...
2๋ ์ ์๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ํ์ ๋ฐ์ ๋ฌ๋ ฅ์ ๋ง๋ค์์ต๋๋ค. ํ์ง๋ง ์ด๋ฒ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์์ด Date ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ์ฌ ๋ง๋ค์์ต๋๋ค. ์ด ๊ณผ์ ์์ Date ๊ฐ์ฒด์ ์ด์ ๋ณด๋ค ์นํด์ง ๋๋์ ๋ฐ์์ต๋๋ค. ์ฌ์ ํ ํท๊ฐ๋ฆฌ๋ ๋ฉด์ด ์์ง๋ง ํ ๋ฒ ์ฌ์ฉ์ ํ์ผ๋ ๋ค์๋ฒ์ ๋์ฑ ์ต์ํ๊ฒ ์ฌ์ฉํ ์ ์์ ๊ฒ๋๋ค.
์ด๋ฒ์ ์ ๋ฆฌํ ๊ธ์ ๋ฐํ์ผ๋ก ํ๋ฃจ์คํฐ๋์ ๋ฌ๋ ฅ ๋ก์ง์ ํ ๋ฒ ๋ฆฌํฉํฐ๋ง์ ํ๋ ค๊ณ ํฉ๋๋ค. ๋ค์ ๋ณด๋ ๊ธํ๊ฒ ๊ตฌํํ๋๋ผ ์ฝ๋๊ฐ ๋ง์ด ์ด์ง๋ฌ์ด๋ฐ ์ผ๋ฅธ ๋ฆฌํฉํฐ๋ง ํ๊ณ npm ๋ฐฐํฌ๊น์ง ๋์ ํด๋ด๊ฒ ์ต๋๋ค. ์ด ๋ฐฐํฌํ ๊ฒ์ ํฐ์ฒ์บ ver2์ ์ ์ฉ๋ ํ๋ฉด ๊ต์ฅํ ์ฌ๋ฐ๋ ์๊ฐ์ด ๋ ๊ฒ ๊ฐ๋ค์.