# 개요

Full Calendar는 달과 관련된 작업을 완전히 처리할 수 있는 js 라이브러리이다. 해당 FullCalendar를 Angular에 적용하는 방법에 대해 알아보겠다.


# fullcalendar-angular 설치

- ng g page calendar

캘린더 페이지 생성

- npm install --save @fullcalendar/angular @fullcalendar/daygrid @fullcalendar/interaction


# fullcalendar 모듈 import

- calendar.module.ts 내 FullCalendarModule import

import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { FullCalendarModule } from '@fullcalendar/angular'; // the main connector. must go first import dayGridPlugin from '@fullcalendar/daygrid'; // a plugin import interactionPlugin from '@fullcalendar/interaction'; // a plugin import { AppComponent } from './app.component'; FullCalendarModule.registerPlugins([ // register FullCalendar plugins dayGridPlugin, interactionPlugin ]); //이외의 timeGrid, weekGrid는 필요없으므로, 제외 @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, FullCalendarModule // register FullCalendar with you app ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }


# fullcalendar option setting

- 해당페이지 컴포넌트(calendar.component.ts) 내 calendar options 정의

import { ComponentOnInitViewChild } from '@angular/core';
import { ViewEncapsulation } from '@angular/core';
import { CalendarOptionsEventApiEventInputFullCalendarComponent } from '@fullcalendar/angular';
import enLocale from '@fullcalendar/core/locales/en-au';
import koLocale from '@fullcalendar/core/locales/ko';


@Component({
  selector: 'app-calendar',
  templateUrl: './calendar.page.html',
  styleUrls: ['./calendar.page.css']
  // encapsulation: ViewEncapsulation.None
})

export class CalendarPage implements OnInit {
  calendarOptionsCalendarOptions = {
    locales:[enLocalekoLocale],
    locale: 'ko',
    displayEventTime: false,
    headerToolbar: {
      start: 'today prev,next',
      center: 'title',
      end: ''
    },
    initialView: 'dayGridMonth',
    initialEvents: INITIAL_EVENTS// alternatively, use the `events` setting to fetch from a feed
    weekends: true,
    editable: true,                //event longclick 시, draggable과 resizing(date range 변경)이 가능하게 함(기본값 : false)
    eventDurationEditable: false,  //event longclick & drag 시, 범위 조절 가능하게 하는 기능 Off(기본값 : true)
    eventStartEditable: true,      //event longclick & drag 시, 날짜 이동 가능하게 하는 기능 On(기본값 : true)
    selectable: true,              //long click, long click & drag를 해야만, select가 이루어지고, select callback 반환 // 날짜 배경 Highlight 및 Range 선택가능
    eventOverlap: true,            //해당 날짜에 하나이상의 과업이 있어도, drop 가능(기본값 : true)
    // droppable: true,            //다른 캘린더나 element상에서, drag & drop된 event 허용 여부(기본값 : false)
    // drop                        //다른 캘린더나 element상에서, drag & drop된 event
    // selectMirror: true,         //timegridView에만 적용되는 속성
    eventLongPressDelay: 1000,     //event가 draggable 하게 만들기 위해 걸리는 시간(기본값 : 1초)
    selectLongPressDelay: 1000,    //date가 select 하게 만들기 위해 걸리는 시간(기본값 : 1초)
    // longPressDelay : 1000       //위에 두개를 합친것
    dayMaxEvents: true,            //+버튼으로 표시
    // eventBackgroundColor: 'red',   //기본값 배경색삭 적용
    // eventBorderColor: 'red',       //기본값 테두리색상 적용
    // eventTextColor: 'red',         //기본값 글자색상 적용
    eventDrop: this.handleEventDrop.bind(this),
    dateClick: this.handleDateClick.bind(this), //date short click
    select: this.handleDateSelect.bind(this),   //date long click
    eventClick: this.handleEventClick.bind(this),
    eventsSet: this.handleEvents.bind(this),
    // contentHeight: 'auto', //height 속성이 사라질 수 있음
    height: '90vh'
    /* you can update a remote database when these fire:
    eventAdd:
    eventChange:
    eventRemove:
    */
  };
  currentEventsEventApi[] = [];

  
  @ViewChild('calendar'calendarComponentFullCalendarComponent

  ngOnInit(){
    // this.calendarComponent.getApi().today();
  }

  handleWeekendsToggle() {
    const { calendarOptions } = this;
    calendarOptions.weekends = !calendarOptions.weekends;
  }

  //clickInfo : date(Date), dateStr, allDay, dayEl(HTML Element), view, jsEvent
  handleDateClick(info) {
    // alert('Clicked on: ' + info.dateStr);
    // alert('Coordinates: ' + info.jsEvent.pageX + ',' + info.jsEvent.pageY);
    // alert('Current view: ' + info.view.type);
    // change the day's background color just for fun
    // info.dayEl.style.backgroundColor = 'red';
  }

  //selectionInfo : start(Date), end(Date), startStr, endStr, allDay(true or false), view(현재 calendar view), jsEvent
  handleDateSelect(selectInfo) {
    const title = prompt('Please enter a new title for your event');
    const calendarApi = selectInfo.view.calendar;
    calendarApi.unselect(); // clear date selection
    // alert(selectInfo.startStr);
    if (title) {
      calendarApi.addEvent({
        id: createEventId(),
        title,
        start: selectInfo.startStr,
        end: selectInfo.endStr,
        allDay: selectInfo.allDay
      });
    }
  }

  //event : id(str), groupId(str), allDay(bool), start, end, startStr, endStr, title, url, classNames(arrayOfString, HTML 클래스 네임을 삽입가능),
          //display(auto : all-day 또는 multi-day는 자동으로 block, 시간 있을 경우, list-item, 기타 bacground, inverse-background 속성, none : 보이지 않음 속성 존재)
          //backgroundColor, borderColor, textColor
          //extendedProps에 {키 : 값} 형태로 속성을 추가할 수 있음 
  //dropInfo : event(drop 이후의 event 객체), oldEvent(drop 이전의 event 객체), revert(이전으로 start,end 되돌림)
  handleEventDrop(info) {
    // alert(info.event.title + " was dropped on " + info.event.start.toISOString());
    if (!confirm("Are you sure about this change?")) {
      info.revert();
    }//이동 실패시 또는 undo 요청시, 수행
  }
  //eventClickInfo : event, el(html element), jsEvent, view
  handleEventClick(clickInfo) {
    // alert('Event: ' + clickInfo.event.title);
    // alert('Coordinates: ' + clickInfo.jsEvent.pageX + ',' + info.jsEvent.pageY);
    // alert('View: ' + clickInfo.view.type);
    // change the border color just for fun
    // clickInfo.el.style.borderColor = 'red';
    if (confirm(`Are you sure you want to delete the event '${clickInfo.event.title}'`)) {
      clickInfo.event.remove();
    }
  }

  handleEvents(eventsEventApi[]) {
    this.currentEvents = events;
  }
}
let eventGuid = 0;
const TODAY_STR = new Date().toISOString().replace(/T.*$/''); // YYYY-MM-DD of today

export const INITIAL_EVENTSEventInput[] = [
  {
    id: createEventId(),
    title: 'All-day event',
    start: TODAY_STR
  },
  {
    id: createEventId(),
    title: 'Timed event',
    start: TODAY_STR + 'T12:00:00'
  }
];

export function createEventId() {
  return String(eventGuid++);
}



# component html 설정

<ion-header>
  <ion-toolbar>
    <ion-title>calendar</ion-title>
  </ion-toolbar>
</ion-header>
<div id="calendar-container" style="height:100%;">
  <full-calendar #calendar
          [options]='calendarOptions'>
  </full-calendar>
</div>


# 스타일 지정

#calendar-container ::ng-deep .fc-header-toolbar {
    margin-bottom0em;
}

# 출처

https://fullcalendar.io/docs/angular

https://github.com/fullcalendar/fullcalendar-example-projects/tree/master/angular

'[DEV] App Dev ∕ Web Front > Framework ∕ Angular' 카테고리의 다른 글

Karma Unit Tester  (0) 2020.08.06
Angular Project 구조  (0) 2020.08.05
Angular Routing  (0) 2020.08.03
Angular 일반지식  (0) 2020.08.03
Angular Directive (미완)  (0) 2020.08.03
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기