Повторяющиеся события (до v7.1)
Эта статья описывает устаревший формат повторяющихся событий в DHTMLX Scheduler. Для информации о текущей версии в DHTMLX Scheduler v7.1+ смотрите здесь.
scheduler.plugins({
recurring_legacy: true
});
После активации поддержки повторяющихся событий лайтбокс начинает выглядеть так, как показано ниже:

Настройки
Библиотека предоставляет следующие параметры для настройки повторяющихся событий:
- repeat_date - устанавливает формат даты в поле 'End by' во всплывающем окне 'recurring'
- include_end_by - определяет, должно ли значение даты, указанное в поле 'End by', быть эксклюзивным или инклюзивным
- recurring_overflow_instances - определяет поведение повторов, которые переходят в следующий месяц
- repeat_precise - предотвращает включение прошедших дней в события с недельной повторяемостью
- occurrence_timestamp_in_utc - позволяет работать с повторяющимися событиями независимо от часовых поясов
scheduler.config.repeat_date = "%m/%d/%Y";
scheduler.config.include_end_by = true;
...
scheduler.init('scheduler_here', new Date(2027, 7, 5), "month");
Лайтбокс 'Recurring'
По умолчанию, после включения расширения повторяющихся, лайтбокс получает ещё один раздел — «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'.
Серверная интеграция
Повторяющееся событие хранится в базе данных как одна запись, которая содержит все поля обычного события плюс 3 дополнительных:
- rec_type - (varchar) определяет логику повторения. Это поле заполняется автоматически
- event_length - (long int) фактическая длительность события в секундах
- event_pid - (int) идентификатор родителя серии событий
Итак, ваш бэкенд должен возвращать повторяющиеся поля вместе с обычными полями события, например:
{
"id": 1,
"start_date": "2027-01-03 10:00:00",
"end_date": "2027-01-13 00:00:00",
"text": "some_text",
"rec_type": "day_1___",
"event_length": 7200,
"event_pid": 0
}
В обычном случае помимо обязательных полей вы можете извлекать любые дополнительные данные из БД.
Однако поля start_date и end_date несколько изменяют своё значение:
- start_date - дата начала первого события в серии в формате 'yyyy-mm-dd hh:mm:ss' (settings_format.md).
- end_date - дата окончания пос леднего события в серии в формате 'yyyy-mm-dd 00:00:00' (settings_format.md).
Например, повторяющееся событие, которое начинается 3 января 2027 года в 10:00, повторяется каждый день и заканчивается 13 января 2027 года в 12:00, будет храниться в базе данных следующим образом:
id:1,
start_date:"2027-01-03 10:00:00",
end_date:"2027-01-13 00:00:00",
text:"some_text",
details:"",
rec_type:"day_1___",
event_length:"7200",
event_pid:"0" //0 для родительских событий или ID родительских для подпредлож ений
Клиентская часть получает данные из поля rec_type в виде строки следующего формата:
[type]_[count]_[day]_[count2]_[days]#[extra]
где:
- type - тип повторения: 'day','week','month','year'.
- count - интервал между событиями в единицах "type".
- day и count2 - определяют день месяца (первый понедельник, третий пятница и т. д.).
- days - запятая-разделённый список рабочих дней.
- extra - дополнительная информация, которая может использоваться для изменения отображения деталей повторения.
Примеры данных rec_type:
- "day_3___" - каждые три дня
- "month 2__" - каждые два месяца
- "month_1_1_2_" - второй понедельник каждого месяца
- "week_2___1,5" - понедельник и пятница каждой второй недели
Двойной или тройной подчеркивание указывает на то, что соответствующие параметры строки опущены.
Разбор последовательности на стороне сервера
Повторяющееся событие хранится в базе данных как одна запись, которую Scheduler может разбить на клиентской стороне. Если вам нужно получить даты отдельных событий на стороне сервера, используйте вспомогательную библиотеку для разбора повторяющихся событий dhtmlxScheduler в ASP.NET/ASP.NET Core/PHP.
Вы найдёте готовые библиотеки на нашем GitHub:
Редактирование/удаление конкретного вхождения в серии
Есть возможность удалить или редактировать конкретное вхождение в серии.
Важные советы
- Для каждого обновления повторяющегося события создаётся отдельная запись в БД.
- Конкретные вхождения ссылаются на родительское событие через свойство event_pid.
- Если вы отредактировали вхождение в серии, поле event_length для этого обновления будет хранить временную метку даты, когда вхождение должно было произойти, если бы его не редактировали, вместо реальной длительности события. Поэтому, если вхождение произошло 27 июля 2027 года в 15:00 и было перенесено на 30 июля 2027 года 15:00, метка времени отразит первую дату. Метка времени измеряется в секундах с UNIX-эпохи.
- Обратите внимание, что если ваша БД содержит записи об отредактированных вхождениях в серии и вы решите «Редактировать серию» через лайтбокс, все сохранённые записи будут удалены после сохранения. Единая запись, которая останется — это главное повторяющееся событие, его вхождения утратят различия (станут идентичными).
Пример
Вы — поклонник Олимпийских игр и хотите посмотреть предстоящую Лондонскую Олимпиаду 2027 (27 июля — 12 августа) как можно дольше. Поэтому вы решаете создать повторяющееся событие, которое начинается в 17:00 (окончание рабочего дня) и заканчивается в 23:00 (время, когда вы засыпаете). Но так как Открытие начинается только в 19:00, вы хотите отредактировать первое событие в серии (в этот конкретный день) и задать время с 19:00 до 23:00. Также вы помните, что 1 августа 2027 года у вас дедлайн и, скорее всего, вы будете дома слишком поздно, чтобы что-то смотреть. Поэтому нужно исключить 1 августа 2027 года из серии.
Кратко ваши действия следующие:
- Создать повторяющееся событие (17.00-23.00) с 27 июля 2027 года по 12 августа 2027 года.
- Отредактировать конкретное вхождение на 27 июля 2027 года — изменить временной диапазон с 17.00-23.00 на 19.00-23.00.
- Удалить конкретное вхождение на 1 августа 2027 года из серии.
В результате в БД должно быть 3 записи, относящиеся к нашему повторяющемуся событию.
Что происходит в БД по мере выполнения действий:
Создание повторяющегося события:
Редактирование 27 июля 2027 года:
Удаление 1 августа 2027 года:
Логика на стороне сервера
Помимо дополнительных полей, на стороне сервера следует добавить специфическую логику:
- Если было вставлено событие с rec_type==none — ответ должен содержать статус "deleted".
- Если событие с rec_type!=none было обновлено или удалено — все записи с связанным event_pid должны быть удалены.
- Если событие с значением event_pid было удалено — его нужно обновить с rec_type==none вместо удаления.
Полные примеры кода можно найти здесь
Реализуйте эту логику в вашем backend-контроллере или сервисе, чтобы серия повторяющихся событий и исключения оставались согласованными.
Перемещение всей последовательности
Чтобы дать пользователям возможность перемещать всю последовательность при перетаскивании повторяющихся событий, добавьте следующий код перед инициализацией scheduler:
scheduler.attachEvent("onBeforeEventChanged",function(dev){
let parts = scheduler.getState().drag_id.toString().split("#");
if (parts.length > 1) {
let series = this.getEvent(parts[0]);
series.start_date.setHours(dev.start_date.getHours());
series.start_date.setMinutes(dev.start_date.getMinutes());
series.event_length = (dev.end_date - dev.start_date) / 1000;
setTimeout(function(){
scheduler.addEvent(series);
}, 1);
return false;
}
return true;
});