Еще один день, еще один рецепт HarpJS . Можете ли вы сказать, что меня волнует в последнее время? Для сегодняшней демонстрации я создал простой динамический календарь для HarpJS. Вероятно, есть много разных способов справиться с этим (вы можете просто встроить Календарь Google, как я здесь опишу ), но вот как я это решил.
Я решил использовать плагин FullCalendar jQuery для отображения календаря. Я использовал его раньше с демонстрацией ColdFusion, и мне нравится, как легко это использовать. Я также знал, что он поддерживает загрузку событий из источника Ajax. HarpJS позволяет создавать больше, чем просто динамические HTML-страницы. Вы также можете создавать динамические файлы XML и JSON. Этот рецепт описывает, как вы можете генерировать XML для RSS-канала. Аналогичный метод может быть использован для генерации JSON.
Я начал с создания папки событий. Внутри этой папки я создал несколько файлов для представления моих событий. Я не делаю с этим ничего особенного, поэтому не стану делиться кодом. Затем я создал файл _data.json. Это то, что будет управлять подачей JSON.
{
"a":{
"title":"Event A",
"date":"2/14/2014",
"allDay":true
},
"b":{
"title":"Event B",
"date":"2/13/2014 2:00 PM"
},
"events":{
"layout":false
}
}
Первые два пункта представляют мои события. Название и дата должны иметь смысл. Я объясню весь день через секунду. Последний элемент представляет файл, который будет генерировать мой канал JSON. По умолчанию Harp оборачивает ваши страницы в шаблоны макета. Но для фида JSON этот макет нарушит код, который его анализирует. Добавляя layout: false, я говорю Harp’у не переносить этот файл с обычным макетом сайта. (Это вызывает еще одну небольшую проблему, и в конце я расскажу об этом подробнее.)
Далее — я создал свой интерфейс. Это взято прямо из файлов примеров FullCalendar, так что это не слишком волнует, но вот оно:
<link href='/fullcalendar/fullcalendar.css' rel='stylesheet' />
<link href='/fullcalendar/fullcalendar.print.css' rel='stylesheet' media='print' />
<script src='/lib/moment.min.js'></script>
<script src='/lib/jquery.min.js'></script>
<script src='/lib/jquery-ui.custom.min.js'></script>
<script src='/fullcalendar/fullcalendar.min.js'></script>
<script>
$(document).ready(function() {
$('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
editable: true,
timezone:"America/Chicago",
events: {
url: '/events/events.json',
error: function() {
$('#script-warning').show();
}
},
loading: function(bool) {
$('#loading').toggle(bool);
}
});
});
</script>
<div id='script-warning'>
crap broke.
</div>
<div id='loading'>loading...</div>
<div id='calendar'></div>
Единственное, что здесь действительно интересно, это опция URL в полном календаре. Обратите внимание, что я указываю на /events/events.json. Мой настоящий файл — events / events.json.ejs. Harp обслужит его без расширения EJS и даже автоматически использует правильный тип контента на основе расширения JSON. Прохладно! Теперь давайте посмотрим на код.
[
<%
var events = Object.keys(public.events._data);
for(var i=0; i<events.length; i++) {
if(events[i] !== "events") {
event = public.events._data[events[i]];
%>
{
"title":"<%- event.title %>",
"start":"<%- event.date %>",
"url":"/events/<%- events[i] %>.html"
<% if(event.allDay) { %>
,"allDay":<%- event.allDay %>
<% } %>
}
<% if(i+2 < events.length) { %>,<% } %>
<%
}
}
%>
]
Хорошо, не самый красивый код, но давайте разберем его. Я начинаю с того, что получаю ключи от моих данных и зацикливаюсь на них. Я пропускаю ключ событий — помните, он есть только для того, чтобы я мог отключить макет. Для каждого события я вывожу название и дату. Начальная метка используется там, потому что именно этого хочет FullCalendar. Говоря о — FullCalendar также требует, чтобы вы сообщили ему, когда событие заканчивается в течение всего дня. Если вы этого не сделаете, он делает предположение о времени. Вот почему я включил allDay в свои данные JSON, и вы можете увидеть меня здесь. Наконец, я использую немного логики, чтобы определить, нахожусь ли я в конце цикла. Если я не, я вывожу запятую.
Так что да — это безобразно — и мне было довольно легко это сломать. Вывод был хорош — но код был грубым. Затем я понял, что для меня будет глупо создавать JSON, когда сервер может сделать это вместо этого. Вот вторая версия:
<%
var eventData = [];
var events = Object.keys(public.events._data);
for(var i=0; i<events.length;i++) {
if(events[i] !== "events") {
var eventOb = {};
event = public.events._data[events[i]];
eventOb.title = event.title;
eventOb.start = event.date;
eventOb.url = "/events/" + events[i] + ".html";
if(event.allDay) {
eventOb.allDay = event.allDay;
}
eventData.push(eventOb);
}
}
%>
<%- JSON.stringify(eventData) %>
Черт побольше чище, верно? И тогда я заканчиваю простым вызовом JSON.stringify. Гораздо проще Вот и все! Вот снимок экрана с календарем, отображающим события, поддерживаемые HarpJS, и динамический канал JSON.