FullCalendar 달력 내부 이벤트 직접 정의하기

강풍윤·2022년 10월 23일

1. 구현목표

달력에 들어가는 이벤트 박스를 안에 들어갈 내용이나 크기 색상들을 제가 원하는 방식대로 꾸며주고 싶었습니다. 이와 관련해서 검색하면 대부분 FullCalendar에서 미리 정의한 속성으로 접근하여 설명하기 때문에 제가 원하는 부분까지 정의할 수 없었습니다. 따라서 FullCalendar 문서를 더 깊게 찾아보면서 달력 내부 이벤트들을 정의하는 방법에 대해 알아보았습니다.

2. 해결방안

FullCalendar에서 제공하는 이벤트 객체 속성인 extendedProps와 HTML의 요소 중 하나인 dataset을 이용하면 달력 내부 이벤트들을 직접 정의할 수 있습니다.

2-1) extendedProps(FullCalendar Event Object property)

기본적으로 이벤트 객체(Event Object)의 모든 속성(properties)들은 Read-Only(변경불가한)이기 때문에 FullCalendar에서 제공하는 이벤트 객체 속성만 사용할 수 있습니다.


하지만, 이벤트 파싱을 하는 동안에 비표준속성(non-standard properites)이 extendedProps으로 이동할 수 있도록 이벤트 객체의 또 다른 속성을 제공하고 있습니다. 즉, 다음과 같이 extendedProps을 사용하여 이벤트 객체의 속성을 직접 정의할 수 있게 됩니다. 그리고 이는 이벤트 객체의 하나의 속성처럼 동작할 수 있습니다.

2-2) dataset(HTML Element)

  • html 코드
<!-- dataset 선언하기 -->
<div id="user" data-id="1234567890" data-user="johndoe" data-date-of-birth>
  John Doe
</div>
  • JavaScript 코드
const el = document.querySelector('#user');

// 아래와 같이 접근할 수 있습니다
// el.id === 'user'
// el.dataset.id === '1234567890'
// el.dataset.user === 'johndoe'
// el.dataset.dateOfBirth === ''

// 데이터 속성 설정방법
el.dataset.dateOfBirth = '1960-10-03';
// Result on JS: el.dataset.dateOfBirth === '1960-10-03'
// Result on HTML: <div id="user" data-id="1234567890" data-user="johndoe" data-date-of-birth="1960-10-03">John Doe</div>

delete el.dataset.dateOfBirth;
// Result on JS: el.dataset.dateOfBirth === undefined
// Result on HTML: <div id="user" data-id="1234567890" data-user="johndoe">John Doe</div>

if (!('someDataAttr' in el.dataset)) {
  el.dataset.someDataAttr = 'mydata';
  // Result on JS: 'someDataAttr' in el.dataset === true
  // Result on HTML: <div id="user" data-id="1234567890" data-user="johndoe" data-some-data-attr="mydata">John Doe</div>
}

dataset은 HTML 요소의 하나의 속성으로 사용가능한 값입니다. 위의 코드와 같이 속성값을 "data-" 뒤에 식별자 이름을 직접 정의하여 CSS 속성선택자나 JavaScript getAttribute() 메서드로 접근이 가능한 덕분에 원하는 값을 HTML요소의 속성으로써 이용하고 싶을 때 사용 가능합니다.

3. 구현코드


    var calendar =null;			

    document.addEventListener('DOMContentLoaded', function() {
        var Calendar = FullCalendar.Calendar;
        var Draggable = FullCalendar.Draggable;

        var containerEl = document.getElementById('external-events');
        var calendarEl = document.getElementById('calendar');
        var checkbox = document.getElementById('drop-remove');

        new Draggable(containerEl, {
            itemSelector: '.fc-event',
            eventData: function(eventEl) {
                var dataset = eventEl.dataset;

                return {
                    title: eventEl.innerText,
                    extendedProps: {
                        chargetypeno: dataset.chargetypeno,
                        typecolor: dataset.typecolor,
                    },
                
                };
                
            }
            
        });

        // 달력 초기화
        // -----------------------------------------------------------------
        
        calendar = new Calendar(calendarEl, {
            headerToolbar: {
                left: '',
                center: 'title',
                right: 'prev,next today',
            },
            initialView: 'dayGridMonth',
            locale: 'ko',
            events: all_events,
            editable: false,
            droppable: true,
            drop: function(info) {
                ...
            },
            //eventContent는 이벤트의 요소를 생성하는 함수
            eventContent: function (info) {
                let italicEl = document.createElement('div')
                            
                italicEl.innerHTML = '<div class="calender-droped-event" data-chargetypeno="'+info.event.extendedProps.chargetypeno+'" data-typecolor="'+info.event.extendedProps.typecolor+'">'+info.event.title+'</div>';

                let arrayOfDomNodes = [italicEl]
                return { domNodes: arrayOfDomNodes }
            },
             ...
        });

        //달력 렌더링
        calendar.render();

    });

Draggable이라는 객체 안에 eventData메서드의 리턴값으로 extendedProps이라는 속성이있습니다. dataset으로 접근해서 각각의 이벤트의 고유번호(chargetypeno)를 설정해준 값으로 생성,수정, 삭제할 수 있도록 직접 정의하였습니다.

그리고 달력을 렌더링할때, 달력 객체의 eventContent메서드를 통해 DB에 저장된 이벤트의 제목(title), 고유색상(typecolor), 고유번호(chargetypeno) 정보를 dataset으로 생성할 수 있도록 설정했습니다.

참고사이트
1. Event Object FullCalendar 문서
2. dataset MDN 문서

profile
https://github.com/KANGPUNGYUN

0개의 댓글