[Angular] 달력만들기
Angular를 이용한 간단한 카렌다 제작
angular를 이용하여 달력을 만들는 소스 입니다.
- calendar.ts
import * as _ from 'underscore';
import * as moment from 'moment';
import { HttpClient, HttpHeaders } from '@angular/common/http';
..........
export class AttendancePage {
attendances = []; // 출석일{mmdd : YYYY-MM-DD HH:ii:ss}
ym: any;
weeks: any[] = [];
month: any;
todayNumber = 0;
constructor(
private http: HttpClient,
) {
// 출석사항을 가져온다.
this.attendance();
// 카렌다를 만든다.
this.ym = moment();
this.month = this.ym.clone(); // 선택된 날짜 정보를 복사한다.
}
private attendance() {
this.http.get('/attendance').subscribe((res: any) => {
this.attendances = res.items;
const start = this.ym.clone();
start.date(1); // 선택된 달의 첫번째 날짜 객체
this.removeTime(start.day(0)); // 이달의 첫일의 일요일 날짜의 객체를 시작일로 세팅.
this.buildMonth(start, this.month); // scope와 시작일, 해당 월의 정보를 넘긴다.
});
}
/**
* 출석처리하기
*/
public attendanceCheck(day: any) {
if (day.active) {
this.http.post('/attendance').subscribe((res: any) => {
if (res.error) {
this.snackbarSvc.show(res.error);
} else {
this.snackbarSvc.show('출석이벤트 복채가 지급되었습니다!!', {type: 'success'});
// 현재 액티브를 비활성화 하기
_.each(this.weeks, (week, i) => {
_.each(week, (days, j) => {
_.each(days, (data: any, j) => {
data.active = false;
})
})
});
}
});
}
}
private buildMonth(start: any, month: any) {
// 전달 받은 정보로 해당 월의 정보를 만듬.
this.weeks = [];
const date = start.clone();
let done = false, monthIndex = date.month(), count = 0;
while (!done) {
// start로 넘어온 일을 시작으로 달의 주정보를 생성 weeks 배열에 추가한다.ㅣ
const week = { days: this.buildWeek(date.clone(), month) };
this.weeks.push(week);
date.add(1, 'w'); // 다음 주로 이동.
done = count++ > 2 && monthIndex !== date.month(); // 달이 넘어 가면 멈춘다.
monthIndex = date.month();
}
}
private buildWeek(date: any, month: any) {
// 한주의 첫번쨰 날과 달의 정보를 받는다.
const days = []; // 총 7일의 정보가 들어간다.
for (let i = 0; i < 7; i++) {
let isToday = false;
let showIcon = false;
let number = date.date();
let active = false
if (date.isSame(new Date(), 'day')) {
isToday = true;
showIcon = true;
this.todayNumber = date.date();
}
// 이전의 출석여부를 확인하여 출석된 날은 아이콘을 노출한다.
const hasAttend = _.find(this.attendances, (attend: any) =>{
return attend.date === date.format("YYYY-MM-DD") ;
});
if (hasAttend) {
showIcon = true;
}
if (isToday && !hasAttend) {
active = true;
}
days.push({
number: number,
isCurrentMonth: date.month() === month.month(),
isToday: isToday,
active,
showIcon,
date
});
date = date.clone();
date.add(1, 'd');
}
return days;
}
private removeTime(date: any) {
// 넘어온 날짜의 제일 첫일[일요일 00:00] 으로 맞추는 역활, 한주의 일요일로 맞추는 역활
return date.day(0).hour(0).minute(0).second(0).millisecond(0);
}
}
- calendar.html
<div class="calendar">
<div class="dash">
<strong>{{ym | moment:'YYYY년 MM월'}}</strong>
</div>
<div class="week names">
<span class="day sun">일</span>
<span class="day">월</span>
<span class="day">화</span>
<span class="day">수</span>
<span class="day">목</span>
<span class="day">금</span>
<span class="day sat">토</span>
</div>
<div class="week" *ngFor="let week of weeks">
<div *ngFor="let day of week.days" class="day" [ngClass]="{ 'active': day.active, 'different-month': !day.isCurrentMonth, 'selected': day.date.isSame(ym ) }" (click)="attendanceCheck(day)">
<span>{{day.number}}</span>
</div>
</div>
</div>