Эта статья описывает устаревший формат повторяющихся событий в DHTMLX Scheduler. Для информации о текущей версии в DHTMLX Scheduler v7.1+ смотрите здесь.
По умолчанию Scheduler не поддерживает повторяющиеся события. Чтобы добавить эту функциональность, необходимо включить специальное расширение recurring_legacy на вашей странице.
scheduler.plugins({
recurring_legacy: true
});
После включения поддержки повторяющихся событий в лайтбоксе появится дополнительный раздел, как показано ниже:
Библиотека предоставляет несколько опций для настройки повторяющихся событий:
scheduler.config.repeat_date = "%m/%d/%Y";
scheduler.config.include_end_by = true;
...
scheduler.init('scheduler_here', new Date(2019, 7, 5), "month");
Related sample: Recurring events
После включения расширения для повторяющихся событий в лайтбоксе появляется дополнительный раздел с названием "Repeat event". По умолчанию конфигурация лайтбокса для повторяющихся событий выглядит так:
[
{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
Повторяющееся событие хранится в базе данных как одна запись, которая содержит все стандартные поля события плюс три дополнительных:
Типичный запрос к коннектору может выглядеть так:
$scheduler->render_table("events_rec","event_id",
"start_date,end_date,text,rec_type,event_pid,event_length");
Помимо этих обязательных полей, вы можете получать любые другие данные из вашей базы.
Обратите внимание, что значения start_date и end_date имеют здесь немного иное значение:
Например, повторяющееся событие, начинающееся 3 января 2019 года в 10:00, повторяющееся ежедневно и заканчивающееся 13 января 2019 года в 12:00, будет храниться так:
id:1,
start_date:"2019-01-03 10:00:00",
end_date:"2019-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]
где:
Примеры значений rec_type:
Примечание: двойное или тройное подчёркивание означает, что параметры пропущены.
Повторяющиеся события хранятся в базе как отдельные записи, которые Scheduler может разбивать на клиенте. Если вам нужно получить отдельные даты повторов на сервере, доступны вспомогательные библиотеки для разбора повторяющихся событий для ASP.NET/ASP.NET Core и PHP.
Эти библиотеки доступны на GitHub:
Можно редактировать или удалять отдельные повторы внутри серии повторяющихся событий.
Представьте, что вы поклонник Олимпийских игр и хотите смотреть Лондонскую Олимпиаду 2012 (27 июля – 12 августа) как можно больше. Вы создаёте повторяющееся событие с 17:00 (конец рабочего дня) до 23:00 (отбой). Однако, поскольку церемония открытия начинается в 19:00, вы хотите изменить первый повтор на время с 19:00 до 23:00. Также вы знаете, что 1 августа 2012 у вас дедлайн, и, вероятно, вы ничего не посмотрите, поэтому хотите удалить повтор этого дня из серии.
В результате в базе будет 3 записи, относящиеся к повторяющемуся событию.
Создание повторяющегося события:
Редактирование 27 июля 2012:
Удаление 1 августа 2012:
Помимо дополнительных полей, серверный контроллер должен реализовать определённую логику:
Полные примеры кода доступны здесь
Если вы используете PHP Connector, серверный код может выглядеть так:
function delete_related($action){
global $scheduler;
$status = $action->get_status();
$type = $action->get_value("rec_type");
$pid = $action->get_value("event_pid");
// При изменении или удалении серии удаляем все связанные события
if (($status == "deleted" || $status == "updated") && $type != ""){
$scheduler->sql->query("DELETE FROM events_rec WHERE
event_pid='" . $scheduler->sql->escape($action->get_id()) . "'");
}
if ($status == "deleted" && $pid != 0){
$scheduler->sql->query("UPDATE events_rec SET rec_type='none' WHERE
event_id='" . $scheduler->sql->escape($action->get_id()) . "'");
$action->success();
}
}
function insert_related($action){
$status = $action->get_status();
$type = $action->get_value("rec_type");
if ($status == "inserted" && $type == "none")
$action->set_status("deleted");
}
$scheduler->event->attach("beforeProcessing","delete_related");
$scheduler->event->attach("afterProcessing","insert_related");
Чтобы разрешить пользователю перетаскивать всю последовательность повторяющихся событий, добавьте следующий код перед инициализацией Scheduler:
scheduler.attachEvent("onBeforeEventChanged", function(dev){
var parts = scheduler.getState().drag_id.toString().split("#");
if (parts.length > 1) {
var 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;
});
Начиная с версии 4.2, dhtmlxScheduler позволяет настраивать HTML-форму, используемую в блоке 'recurring' лайтбокса.
Давайте начнем с примера. Предположим, вы хотите убрать опции повторения 'monthly' и 'yearly', а также оставить выбор "без даты окончания" доступным для всех событий (то есть убрать секцию установки окончания повторения).
<div class="dhx_form_repeat" id="my_recurring_form"> <form>
<div>
<select name="repeat">
<option value="day">Ежедневно</option>
<option value="week">Еженедельно</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">
Повторять каждую неделю по дням:<br />
<label><input type="checkbox" name="week_day" value="1" />Понедельник</label>
<label><input type="checkbox" name="week_day" value="2" />Вторник</label>
<label><input type="checkbox" name="week_day" value="3" />Среда</label>
<label><input type="checkbox" name="week_day" value="4" />Четверг</label>
<label><input type="checkbox" name="week_day" value="5" />Пятница</label>
<label><input type="checkbox" name="week_day" value="6" />Суббота</label>
<label><input type="checkbox" name="week_day" value="0" />Воскресенье</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-разметку блока повторения lightbox для разных языков можно найти в папке 'scheduler\sources\locale\recurring\'.
Например, для английской локали используйте файл 'scheduler\sources\locale\recurring\repeat_template_en.htm'.
В целом, блок повторения в lightbox состоит из 3 основных групп элементов управления:
1) Элементы для выбора типа повторения. Эти input-элементы должны иметь имя 'repeat' и одно из следующих значений: 'daily', 'weekly', 'monthly', 'yearly'. Ваша форма должна содержать хотя бы один input с именем 'repeat' и значением. Можно использовать radio-кнопки, select или даже скрытый input для установки значения по умолчанию.
Вот несколько допустимых примеров выбора типа повторения в форме:
<label><input type="radio" name="repeat" value="day" />Ежедневно</label><br />
<label><input type="radio" name="repeat" value="week"/>Еженедельно</label><br />
<label><input type="radio" name="repeat" value="month" />Ежемесячно</label><br />
<label><input type="radio" name="repeat" value="year" />Ежегодно</label>
<select name="repeat">
<option value="day">Ежедневно</option>
<option value="week">Еженедельно</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"/>Каждый
</label>
<input class="dhx_repeat_text" type="text"
name="day_count" value="1" />день<br>
<label>
<input class="dhx_repeat_radio" type="radio"
name="day_type" checked value="w"/>Каждый рабочий день
</label>
</div>
...
</div>
Обратите внимание, что разметку, относящуюся к определённому типу повторения, можно обернуть в div с id в формате "dhx_repeat_<repeat type>", например "dhx_repeat_day". В этом случае она будет отображаться только при выборе соответствующего типа повторения.
3) Элементы для задания окончания повторения. Это определяется input-элементами с именем 'end'.
Возможные значения: 'no', 'date_of_end' и 'occurences_count'.
Так же, как и с элементами 'repeat', ваша форма должна содержать хотя бы один input с этим именем.
<div class="dhx_repeat_right">
<label>
<input type="radio" name="end" value="no" checked/>Без даты окончания
</label><br />
<label>
<input type="radio" name="end" value="date_of_end" />После</label>
<input type="text" name="date_of_end" />
<br />
<label>
<input type="radio" name="end" value="occurences_count" />После</label>
<input type="text" name="occurences_count" value="1" />Повторений
</div>
Дата для опции 'date_of_end' должна вводиться в input с именем 'date_of_end'. Аналогично, опция 'occurences_count' использует количество повторений из input с именем 'occurences_count'.
Можно удалить любую опцию или установить её по умолчанию с помощью скрытого input:
<input type="hidden" name="end" value="date_of_end" />
<input type="hidden" name="date_of_end" value="01.01.2016" />
Перед тем как настраивать блок повторения lightbox, учтите следующие моменты:
Имейте в виду, что dhtmlxScheduler не работает напрямую с вашей исходной HTML-формой, а создает её копию внутри шаблона lightbox.
Например:
<input onclick="handler()">
addEventListener(node, "click", function(){...})
Наверх