Вывод событий в календарь, опубликованный на странице сайта, востребован различными сервисами, осуществляющими запись клиентов на прием к определенному времени, например, индивидуальные тренировки или языковые курсы, шиномонтаж, маникюрные салоны и т.п.
Для отображения календаря будет использоваться Fullcalendar, на момент написания статьи используется версия 3.8.2. Скачайте дистрибутив fullcalendar, распакуйте исходные коды в директорию hostcmsfiles/jquery/fullcalendar/
В модуле CRM → Дела перейдите в раздел Справочники → Типы и создайте отдельный тип дела для публикации на сайте, запомните идентификатор этого типа. Если требуется, вы можете создать несколько разных типов дел, которые будут публиковаться на сайте.
В макет сайта в секцию <head> внесите подключение скриптов:
<link href='/hostcmsfiles/jquery/fullcalendar/fullcalendar.min.css' rel='stylesheet' />
<link href='/hostcmsfiles/jquery/fullcalendar/fullcalendar.print.min.css' rel='stylesheet' media='print' />
<script src='/hostcmsfiles/jquery/fullcalendar/lib/moment.min.js'></script>
<script src='/hostcmsfiles/jquery/fullcalendar/fullcalendar.min.js'></script>
<script src='/hostcmsfiles/jquery/fullcalendar/locale-all.js'></script>
В CSS макета внесите стиль, при необходимости доработайте стиль и переопределите нужные элементы:
#calendar { max-width: 900px; margin: 0 auto; }
В структуре сайта создайте раздел с названием «Календарь», укажите путь «calendar» и тип «Динамическая страница».
В код "Динамическая страница" внесите:
<script>
$(document).ready(function() {
$('#calendar').fullCalendar({
defaultDate: '<?php echo date('Y-m-d')?>',
locale: 'ru',
timezone: 'local',
timeFormat: 'H:mm',
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
defaultView: 'agendaWeek', // в виде месяца: month, неделя; agendaWeek, день: agendaDay
editable: false,
droppable: false,
eventLimit: false, // allow "more" link when too many events
// Отрисовка элемента, здесь можете добавить дополнительные стили
eventRender: function(event, element)
{
element.attr('data-event-id', event.id);
$(element).css({'background-color': '#fbfbfb'});
},
// JSON-запрос данных
events: function(start, end, timezone, callback)
{
var ajaxData = {};
ajaxData['_'] = Math.round(new Date().getTime());
ajaxData['start'] = start.unix();
ajaxData['end'] = end.unix();
$.ajax({
url: './?loadEvents',
type: 'POST',
dataType: 'json',
data: ajaxData,
success: function(result) {
var events = (result['events'] && result['events'].length) ? result['events'] : [];
callback(events);
}
});
}
});
});
</script>
<div id="calendar"></div>
в код "Настройки динамической страницы" внесите:
<?php
if (!is_null(Core_Array::getRequest('loadEvents')))
{
Core_Session::close();
// Идентификатор (или массив идентификаторов) типа дела, которые выводить в клиентском разделе
$event_type_id = 6;
$iStart = intval(Core_Array::getPost('start'));
$iEnd = intval(Core_Array::getPost('end'));
$aReturn = array();
$start = date('Y-m-d H:i:s', $iStart);
$end = date('Y-m-d H:i:s', $iEnd);
$aJson = array();
$oEvents = Core_Entity::factory('Event');
$oEvents
->queryBuilder()
->where('event_type_id', is_array($event_type_id) ? 'IN' : '=', $event_type_id)
//->where('completed', '=', 0)
->open()
->where('start', 'BETWEEN', array($start, $end))
->setOr()
->where('finish', 'BETWEEN', array($start, $end))
->close()
->limit(200);
$aEvents = $oEvents->findAll(FALSE);
foreach ($aEvents as $oEvent)
{
$oTmpEvent = new StdClass();
$oTmpEvent->id = $oEvent->id;
$oTmpEvent->title = $oEvent->name;
if (!is_null($oEvent->event_type_id))
{
$oTmpEvent->textColor = '#262626';
$oTmpEvent->borderColor = $oEvent->Event_Type->color;
}
else
{
$oTmpEvent->textColor = '#2dc3e8';
$oTmpEvent->borderColor = '#2dc3e8';
}
// c - дата в формате стандарта ISO 8601
$oTmpEvent->start = date('c', Core_Date::sql2timestamp($oEvent->start));
$oTmpEvent->allDay = $oEvent->all_day ? TRUE : FALSE;
if (!is_null($oEvent->finish) && $oEvent->finish != '0000-00-00 00:00:00')
{
$oTmpEvent->end = $oEvent->all_day
? date('Y-m-dT00:00:00', Core_Date::sql2timestamp($oEvent->finish) + 60)
: date('c', Core_Date::sql2timestamp($oEvent->finish));
}
$aJson['events'][] = $oTmpEvent;
}
$aJson['countEvents'] = isset($aJson['events']) ? count($aJson['events']) : 0;
Core::showJson($aJson);
}
Идентификатор выводимого типа дел задается в переменной $event_type_id, если необходимо выводить несколько типов, то задайте массив с идентификаторами типов, например:
$event_type_id = array(6, 7, 9);
Проверьте в клиентском разделе правильность отображения календаря:
В случае, если календарь публикуется также и на главной странице, то в коде календаря опцию запроса url
$.ajax({ url: './?loadEvents', type: 'POST',
замените на вариант с указанием полного пути к странице
$.ajax({ url: '/calendar/?loadEvents', type: 'POST',