[Angular] 달력만들기

[Angular] 달력만들기 updated_at: 2024-02-13 12:06

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>
평점을 남겨주세요
평점 : 5.0
총 투표수 : 1

질문 및 답글