반복 이벤트는 이벤트 캘린더 애플리케이션에서 유용하게 사용되는 기능으로, 사용자가 원하는 간격으로 반복되는 이벤트를 설정할 수 있게 해줍니다. 7.1 버전부터 Scheduler는 반복 이벤트에 대해 RFC-5545 표준 형식을 채택하고 있습니다.
이 가이드는 Scheduler에서 반복 이벤트를 다루는 방법과 데이터베이스에 저장하는 방법을 설명합니다.
이전 반복 이벤트 형식에 대한 설명은 여기에서 확인할 수 있습니다.
기본적으로 Scheduler에는 반복 이벤트 기능이 활성화되어 있지 않습니다. 이 기능을 사용하려면 페이지에서 recurring 플러그인을 활성화해야 합니다.
scheduler.plugins({
recurring: true
});
반복 이벤트를 활성화하면, 라이트박스 인터페이스에 아래와 같이 추가 섹션이 표시됩니다:
라이브러리는 반복 이벤트를 커스터마이즈할 수 있는 다음 옵션을 제공합니다:
scheduler.config.repeat_date = "%m/%d/%Y";
...
scheduler.init('scheduler_here', new Date(2019, 7, 5), "month");
Related sample: Recurring events
반복 확장 기능을 활성화하면, 라이트박스에 "Repeat event"라는 추가 섹션이 생깁니다. 'recurring' 라이트박스의 기본 구성은 다음과 같습니다:
[
{name:"description", height:130, map_to:"text", type:"textarea" , focus:true},
{name:"recurring", height:115, type:"recurring", map_to:"rec_type",
button:"recurring"},
{name:"time", height:72, type:"time", map_to:"auto"}
];
다른 섹션을 추가할 수 있지만, "recurring"과 "time" 섹션은 반드시 남겨두어야 하며, "time" 섹션은 항상 "recurring" 섹션 뒤에 위치해야 합니다.
Related sample: Recurring events
반복 이벤트는 데이터베이스에 단일 레코드로 저장되며, 표준 이벤트 필드 외에도 몇 가지 추가 속성이 포함됩니다:
rrule 속성은 RFC-5545에서 정의된 iCalendar 형식을 따르며, 빈도, 간격 및 기타 반복 세부 정보를 지정합니다.
우리의 포맷이 iCalendar 포맷과 다른 점은 두 가지가 있습니다:
iCalendar에서는 반복 시리즈의 시작 및 종료 날짜를 RRULE 문자열 내 STDATE와 DTEND 속성으로 포함하는 것이 일반적이지만, 우리 포맷에서는 start_date와 end_date를 별도의 필드로 저장합니다. 이를 통해 RRULE 문자열을 파싱하지 않고도 날짜별로 반복 이벤트를 더 쉽게 다루고 조회할 수 있습니다.
예를 들어 2024년 6월 1일부터 2024년 12월 1일까지 매주 월요일 반복되는 이벤트 시리즈는 다음과 같이 저장됩니다:
{
"id": 1,
"text": "Weekly Team Meeting",
"start_date": "2024-06-03 09:00:00",
"duration": 3600,
"end_date": "2024-12-02 10:00:00",
"rrule": "FREQ=WEEKLY;INTERVAL=1;BYDAY=MO",
"recurring_event_id": null,
"original_start": null
}
예외(즉, 수정되거나 삭제된 발생)는 상위 시리즈와 연결된 별도의 이벤트 레코드로 저장됩니다. 이러한 예외 레코드는 recurring_event_id, original_start, deleted의 세 가지 추가 속성을 포함합니다. 이를 통해 어떤 인스턴스가 변경 또는 삭제되었는지, 그리고 해당 인스턴스가 메인 시리즈와 어떻게 연결되는지 알 수 있습니다.
표준 iCalendar 포맷과 달리, 예외(수정 또는 삭제된 인스턴스)는 RRULE의 EXDATE 속성에 저장되지 않습니다.
예를 들어, 하나의 수정된 발생과 하나의 삭제된 발생이 있는 반복 시리즈는 다음과 같이 저장됩니다:
[
{
"id": 1,
"text": "Weekly Team Meeting",
"start_date": "2024-06-03 09:00:00",
"duration": 3600,
"end_date": "2024-12-02 10:00:00",
"rrule": "FREQ=WEEKLY;INTERVAL=1;BYDAY=MO",
"recurring_event_id": null,
"original_start": null
},
{
"id": 2,
"text": "Special Team Meeting",
"start_date": "2024-06-10 09:00:00",
"end_date": "2024-06-10 11:00:00",
"rrule": null,
"recurring_event_id": 1,
"original_start": "2024-06-10 09:00:00"
},
{
"id": 3,
"text": "Deleted Team Meeting",
"start_date": "2024-06-17 09:00:00",
"end_date": "2024-06-17 10:00:00",
"rrule": null,
"recurring_event_id": 1,
"original_start": "2024-06-17 09:00:00",
"deleted": true
}
]
2024-06-10 09:00:00
에 예정된 이벤트는 Special Team Meeting
레코드로 대체되고, 2024-06-17 09:00:00
이벤트는 생략됩니다.
수정되거나 삭제된 인스턴스의 rrule은 무시된다는 점에 유의하세요.
또한, 삭제된 발생의 text, start_date, end_date 필드는 Scheduler 동작에 영향을 주지 않습니다.
반복 시리즈 내에서 특정 발생을 삭제하거나 편집할 수 있습니다.
추가 필드 외에, 서버 사이드 컨트롤러는 다음과 같은 로직을 구현해야 합니다:
완전한 코드 예제는 여기에서 확인할 수 있습니다.
4.2 버전부터 dhtmlxScheduler는 라이트박스의 'recurring' 섹션에 대해 커스텀 HTML 폼을 정의할 수 있습니다.
아래는 'monthly'와 'yearly' 반복 옵션을 제거하고, 'no end date' 옵션을 기본값으로 설정(반복 종료 블록 숨김)하는 예시입니다.
<div class="dhx_form_repeat" id="my_recurring_form"> <form>
<div>
<select name="repeat">
<option value="day">Daily</option>
<option value="week">Weekly</option>
</select>
</div>
<div>
<div style="display:none;" id="dhx_repeat_day">
<input type="hidden" name="day_type" value="d"/>
<input type="hidden" name="day_count" value="1" />
</div>
<div style="display:none;" id="dhx_repeat_week">
Repeat every week next days:<br />
<label><input type="checkbox" name="week_day" value="1" />Monday</label>
<label><input type="checkbox" name="week_day" value="2" />Tuesday</label>
<label><input type="checkbox" name="week_day" value="3" />Wednesday</label>
<label><input type="checkbox" name="week_day" value="4" />Thursday</label>
<label><input type="checkbox" name="week_day" value="5" />Friday</label>
<label><input type="checkbox" name="week_day" value="6" />Saturday</label>
<label><input type="checkbox" name="week_day" value="0" />Sunday</label>
<input type="hidden" name="week_count" value="1" />
</div>
</div>
<input type="hidden" value="no" name="end">
</form>
</div>
scheduler.config.lightbox.sections = [
{name:"description", height:130, map_to:"text", type:"textarea" , focus:true},
{name:"recurring", type:"recurring", map_to:"rec_type", button:"recurring",
form:"my_recurring_form"}, {name:"time", height:72, type:"time", map_to:"auto"}
];
라이트박스의 반복 블록에 대한 기본 HTML 구조는 다양한 언어에 맞게 'scheduler\sources\locale\recurring\' 디렉터리에 위치해 있습니다.
예를 들어, 영어 로케일은 'scheduler\sources\locale\recurring\repeat_template_en.htm' 파일을 사용합니다.
라이트박스의 반복 블록은 일반적으로 3가지 그룹의 컨트롤로 구성되어 있습니다:
1) 반복 유형을 선택하는 컨트롤. 이 입력들은 모두 'repeat'라는 이름을 공유하며 값은 'daily', 'weekly', 'monthly', 'yearly' 중 하나입니다.
폼에는 반드시 값이 지정된 'repeat' 입력이 최소 하나 이상 포함되어 있어야 합니다. 라디오 버튼, 셀렉트 드롭다운, 또는 숨겨진 입력을 사용해 기본 유형을 지정할 수 있습니다.
다음은 폼에서 반복 유형을 선택하는 유효한 예시입니다:
<label><input type="radio" name="repeat" value="day" />Daily</label><br />
<label><input type="radio" name="repeat" value="week"/>Weekly</label><br />
<label><input type="radio" name="repeat" value="month" />Monthly</label><br />
<label><input type="radio" name="repeat" value="year" />Yearly</label>
<select name="repeat">
<option value="day">Daily</option>
<option value="week">Weekly</option>
</select>
<input type="hidden" name="repeat" value="day" />
2) 선택된 반복 유형에 따라 반복 상세 설정을 위한 섹션. 예를 들어, 'Daily' 반복 유형 블록은 다음과 같습니다:
<div class="dhx_repeat_center">
<div style="display:none;" id="dhx_repeat_day">
<label>
<input class="dhx_repeat_radio" type="radio"
name="day_type" value="d"/>Every
</label>
<input class="dhx_repeat_text" type="text"
name="day_count" value="1" />day<br>
<label>
<input class="dhx_repeat_radio" type="radio"
name="day_type" checked value="w"/>Every workday
</label>
</div>
...
</div>
특정 반복 유형과 관련된 마크업은 id를 "dhx_repeat_<repeat type>" 형식(예: "dhx_repeat_day")으로 지정한 div로 감쌀 수 있습니다.
이 블록은 해당 반복 유형이 선택될 때만 표시됩니다.
3) 반복 종료 시점을 지정하는 컨트롤. 이 입력의 이름은 'end'입니다.
가능한 값은 'no', 'date_of_end', 'occurences_count'가 있습니다.
'repeat' 컨트롤과 마찬가지로, 폼에는 이 타입의 입력이 최소 하나 이상 포함되어야 합니다.
<div class="dhx_repeat_right">
<label>
<input type="radio" name="end" value="no" checked/>No end date
</label><br />
<label>
<input type="radio" name="end" value="date_of_end" />After</label>
<input type="text" name="date_of_end" />
<br />
<label>
<input type="radio" name="end" value="occurences_count" />After</label>
<input type="text" name="occurences_count" value="1" />Occurrences
</div>
'date_of_end' 모드에서는 'date_of_end'라는 이름의 입력에 날짜를 입력해야 합니다. 마찬가지로, 'occurences_count' 모드에서는 'occurences_count'라는 이름의 입력에서 반복 횟수를 가져옵니다.
원하지 않는 반복 유형을 제거하거나 숨겨진 입력을 사용해 미리 지정할 수 있습니다:
<input type="hidden" name="end" value="date_of_end" />
<input type="hidden" name="date_of_end" value="01.01.2024" />
라이트박스의 반복 블록을 커스터마이즈하기 전에 다음 사항을 반드시 확인하세요:
dhtmlxScheduler는 원본 HTML 폼이 아닌, 해당 폼의 복사본을 라이트박스 템플릿 내부에 생성하여 사용한다는 점을 유념하세요.
예시:
<input onclick="handler()">
addEventListener(node, "click", function(){...})
버전 7.1까지 Scheduler는 반복 이벤트에 대해 커스텀 포맷을 사용했습니다. 이 포맷에 대한 자세한 내용은 여기에서 확인할 수 있습니다.
맨 위로