Еще один день, еще один рецепт 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.