2025. 1. 25. 19:58ㆍCalender Website
캘린더 웹사이트를 만들기 위해 Javascript로 캘린더를 직접 구현하게 만들었다.
[HTML]
calendar-container에는 그게 유저 정보를 나타내는 user-info와 달력을 표시하는 calendar가 있다.
user-info는 current_user에서 받아와 사용자 프로필을 표시하도록 만들어 주었다.
calendar는 calendar-header에 월, 년도를 표시하고 달력을 넘길 수 있는 버튼과, 일정을 추가하는 버튼을 달아주었다.
그리고 실제 달력을 출력하는 calendar-grid는 Javascript에서 구현을 담당한다.
<div class="calendar-container">
<div class="user-info">
<img src="{{ url_for('static', filename='images/profile/woman.png' if user.image_path == ''
else user.image_path) }}" class="profile-picture">
<div>
<p class="user-name">{{ user.username }}</p>
<p class="description">{{ user.description }}</p>
</div>
</div>
<div class="calendar">
<div class="calendar-header">
<button id="currentMonth"></button>
<div class="calendar-buttons">
<button id="prevMonth" class="arrow-button"><img src="{{ url_for('static', filename='images/left-arrow.png') }}" class="arrow-picture"></button>
<button id="nextMonth" class="arrow-button"><img src="{{ url_for('static', filename='images/right-arrow.png') }}" class="arrow-picture"></button>
<button id="addEventButton">Add</button>
</div>
</div>
<div class="calendar-grid" id="calendarGrid"></div>
</div>
</div>
[Javascript]
1. Calendar 클래스 정의
constructor를 사용하여 생성자를 정의해주고 init()로 달력을 초기화 해준다.
class Calendar {
// 생성자
constructor() {
this.date = new Date();
this.currentMonth = this.date.getMonth();
this.currentYear = this.date.getFullYear();
this.days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
this.events = {};
this.init();
}
2. Calendar 초기화
이벤트 리스너를 설정하고, 달력을 렌더링한다.
init() {
this.setupEventListeners();
this.render();
}
3. setupEventListeners()
이벤트 리스너를 설정해준다.
prevMonth 버튼을 클릭하면 전달로 이동, nextMonth 버튼을 클릭하면 다음달로 이동한다.
setupEventListeners() {
document.getElementById('prevMonth').addEventListener('click', () => {
this.currentMonth--;
if (this.currentMonth < 0) {
this.currentMonth = 11;
this.currentYear--;
}
this.render();
});
document.getElementById('nextMonth').addEventListener('click', () => {
this.currentMonth++;
if (this.currentMonth > 11) {
this.currentMonth = 0;
this.currentYear++;
}
this.render();
});
}
4. Calendar 랜더링
render() {
const grid = document.getElementById('calendarGrid');
const monthDisplay = document.getElementById('currentMonth');
grid.innerHTML = '';
monthDisplay.textContent = `${this.getMonthName(this.currentMonth)} ${this.currentYear}`;
this.days.forEach(day => {
const dayHeader = document.createElement('div');
dayHeader.className = 'day-header';
dayHeader.textContent = day;
grid.appendChild(dayHeader);
});
getMonthName(month) {
const months = ['January', 'February', 'March', 'April', 'May', 'June',
'July', 'August', 'September', 'October', 'November', 'December'];
return months[month];
}
- 달력 내용을 초기화시킨다.
- Calendar 객체에 현재 월, 년도가 currentMonth, currentYear에 자장되어 있으므로 이를 불러내어 monthDisplay에 표시해준다.
- this.days에서 Sun~Mon을 불러와 div class='day-header'로 설정한 후 textContent를 넣어 grid에 요일 헤더를 추가
const firstDay = new Date(this.currentYear, this.currentMonth, 1);
const startingDay = firstDay.getDay();
const lastDay = new Date(this.currentYear, this.currentMonth + 1, 0);
const totalDays = lastDay.getDate();
const prevMonthLastDay = new Date(this.currentYear, this.currentMonth, 0).getDate();
firstDay | 현재 날짜 | 2025년 2월 1일 |
startingDay | 현재 날짜의 요일 | 6 (일~토 : 0~6) |
lastDay | 현재 월의 마지막 날짜 | 2025년 2월 28일 |
totalDays | 현재 월의 총날짜 | 28 |
prevMonthLastDay | 전월의 마지막 날짜 | 2025년 1월 31일 |
for (let i = startingDay - 1; i >= 0; i--) {
const prevMonthDate = new Date(this.currentYear, this.currentMonth-1, prevMonthLastDay - i);
this.createDayCell(prevMonthDate, 'other-month');
}
- i는 startingDay-1부터 0까지 순회 (5 -> 0)
- prevmonthDate는 2025년 1월 26일 ~ 2025년 1월 31일까지 순회
- 해당 날짜에 맞추어 class가 other-month인 cell을 생성
const today = new Date();
for (let i = 1; i <= totalDays; i++) {
const currentDate = new Date(this.currentYear, this.currentMonth, i);
const isToday = i === today.getDate() &&
this.currentMonth === today.getMonth() &&
this.currentYear === today.getFullYear();
this.createDayCell(currentDate, isToday ? 'today' : '');
}
- 2025년 2월 1일 ~ 2025년 2월 28일까지 cell을 생성
- 만약 만드는 cell과 현재 날짜가 일치하면 class를 today로 지정
const remainingCells = 42 - (startingDay + totalDays);
for (let i = 1; i <= remainingCells; i++) {
const nextMonthDate = new Date(this.currentYear, this.currentMonth+1, i);
this.createDayCell(nextMonthDate, 'other-month');
}
- 2025년 3월 1일 ~ 2025년 3월 8일
- 42칸 중 남은 칸들을 class가 other-month인 cell로 생성
5. createDayCell
createDayCell(date, className) {
const cell = document.createElement('div');
cell.className = `calendar-cell ${className}`;
cell.dataset.date = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate())).toISOString().split('T')[0];
const dateDiv = document.createElement('div');
dateDiv.className = 'calendar-date';
dateDiv.textContent = date.getDate();
cell.appendChild(dateDiv);
document.getElementById('calendarGrid').appendChild(cell);
}
- 달력 한칸을 나타내는 cell의 클래스를 지정해준다. (현재 월 -> calendar-cell , 다른 월 -> calendar-cell other-month, 오늘 -> calendar-cell today)
- date는 Date 객체로 이를 문자열로 변환하여 '2025-01-01'을 cell.dataset.date로 설정한다.
- 날짜를 나타내는 dateDiv를 cell에 추가한 다음, cell도 grid에 추가한다.
'Calender Website' 카테고리의 다른 글
[Flask] 회원 정보 수정, 탈퇴, 로그아웃 (0) | 2025.01.23 |
---|---|
[Flask] Flask-login을 사용한 로그인 시스템 구현 (0) | 2025.01.16 |
[Flask] Blueprint로 웹 애플리케이션 구조화 (0) | 2025.01.14 |
[Flask] 플라스크로 회원가입 구현하기 (0) | 2025.01.14 |
[Flask] 프로필 이미지 미리보기 및 데이터 베이스에 저장하기 (0) | 2025.01.14 |