73656b44f36a7b833190140e020307c6cd9449ac
Author: Nate Abele
Date: 2009-01-22 18:38:11 -0500
diff --git a/app_controller.php b/app_controller.php
index f832419..5deb5c2 100755
--- a/app_controller.php
+++ b/app_controller.php
@@ -1,7 +1,9 @@
<?php
class AppController extends Controller {
+
var $helpers = array('Html', 'Javascript', 'Ajax', 'Cal','PrintMonth');
+
}
?>
\ No newline at end of file
diff --git a/config/routes.php b/config/routes.php
index 8ff5478..c9ca60b 100755
--- a/config/routes.php
+++ b/config/routes.php
@@ -1,6 +1,20 @@
<?php
-Router::connect ('/', array('controller' => 'calendar', 'action' => 'index'));
-Router::connect ('/import', array('controller' => 'calendar', 'action' => 'import'));
+Router::parseExtensions('rss', 'json');
+
+Router::connect('/', array('controller' => 'events', 'action' => 'index'));
+Router::connect('/import', array('controller' => 'calendar', 'action' => 'import'));
+
+Router::connect(
+ '/:year/:month/:day',
+ array('controller' => 'events', 'action' => 'index', 'month' => null, 'day' => null),
+ array('year' => $Year, 'month' => $Month, 'day' => $Day)
+);
+
+Router::connect(
+ '/events/:year/:month/:day',
+ array('controller' => 'events', 'action' => 'index', 'month' => null, 'day' => null),
+ array('year' => $Year, 'month' => $Month, 'day' => $Day)
+);
?>
\ No newline at end of file
diff --git a/controllers/events_controller.php b/controllers/events_controller.php
new file mode 100755
index 0000000..2e17ea0
--- /dev/null
+++ b/controllers/events_controller.php
@@ -0,0 +1,251 @@
+<?php
+
+class EventsController extends AppController {
+
+ var $components = array('RequestHandler', 'ICal', 'Csv');
+
+ function beforeFilter() {
+ $this->RequestHandler->setContent(array(
+ 'ics' => 'text/calendar',
+ 'csv' => 'application/octet-stream'
+ ));
+ $this->set('isAjax', $this->RequestHandler->isAjax());
+
+ // This is debug code, kill it:
+ $this->Session->destroy();
+ }
+
+ function index ($year = null, $month = null, $day = null) {
+ if ($year == null && $this->Session->check('Calendar.View')) {
+ extract($this->Session->read('Calendar.View'));
+ (intval($year) == 1969) ? $year = $month = $day = null : null;
+ }
+
+ if (empty($year)) {
+ $year = date('Y');
+ }
+ if ($month == null) {
+ $month = date('m');
+ }
+ if (intval($day) < 1) {
+ $day = null;
+ }
+
+ $tmpDay = $day == null ? 1 : $day;
+ $stamp = strtotime($year.'-'.$month.'-'.$tmpDay);
+ $start = date('Y-m-d', $stamp);
+ $end = $start;
+
+ if ($day == null) {
+ $end = date(
+ 'Y-m-d', strtotime('+1 month', $stamp) - (strtotime('+1 day') - strtotime('now'))
+ );
+ }
+
+ $events = $this->Event->find('all', array('conditions' => array(
+ 'Event.start <=' => $end . ' 23:59:59',
+ 'Event.end >=' => $start,
+ )));
+
+ $this->Session->write('Calendar.View', compact('year', 'month', 'day'));
+
+ $isDay = ($day != null);
+ $day = $tmpDay;
+ $events = array_values($events);
+ $this->set(compact('isDay', 'events', 'year', 'month', 'day'));
+ }
+
+ function view($id = null) {
+ if ($this->RequestHandler->prefers('json')) {
+ $event = $this->Event->findById($id);
+ $this->set(compact('event'));
+ return;
+ }
+ $this->setAction('index');
+ }
+
+ function edit($id = null) {
+ $this->data = $this->Event->findById($id);
+
+ $this->data['Event'] = array_merge($this->data['Event'], array(
+ 'start_Date' => date('m/d/Y', strtotime($this->data['Event']['start'])),
+ 'start_Time' => date('g:i a', strtotime($this->data['Event']['start'])),
+ 'end_Date' => date('m/d/Y', strtotime($this->data['Event']['end'])),
+ 'end_Time' => date('g:i a', strtotime($this->data['Event']['end']))
+ ));
+ }
+
+ function save() {
+ if (!empty($this->params['form'])) {
+ $this->Event->create();
+
+ if (!empty($this->data)) {
+ $this->Event->save($this->data);
+
+ if (!isset($this->data['Event']['id']) || empty($this->data['Event']['id'])) {
+ $id = $this->Event->id;
+ } else {
+ $data = $this->Event->findById($this->Event->id);
+ $data = $data['Event'];
+ }
+ } else {
+ // Serialized JavaScript data
+ $this->Event->create();
+ $this->Event->save($this->params['form']);
+ $data = $this->Event->findById($this->Event->id);
+ $data['Event']['__id'] = $this->params['form']['__id'];
+ $data = $data['Event'];
+ }
+ }
+ $this->set(compact('data', 'id'));
+ }
+
+ function delete($id = null) {
+ $this->Event->del($id);
+ }
+
+ function import() {
+ if (!empty($this->data)) {
+
+ $events = array();
+
+ if ($this->data['Event']['file']['type'] == 'text/calendar') {
+ // Parse as iCal
+ $data = $this->ICal->read($this->data['Event']['file']['tmp_name']);
+ if (!is_array($data) || empty($data) || !isset($data['Calendar'])) {
+ $this->Session->setFlash('Invalid import file');
+ return;
+ }
+ $data = $data['Calendar'];
+
+ if (!isset($data[0])) {
+ $data = array($data);
+ }
+
+ foreach ($data as $cal) {
+
+ if (isset($cal['Event'][0])) {
+ // Calendar contains
+ foreach($cal['Event'] as $event) {
+ $events[] = $this->__mapEvent($event);
+ }
+ } elseif (isset($cal['Event'])) {
+ $events[] = $this->__mapEvent($cal['Event']);
+ }
+ }
+ } else {
+ // Parse as CSV
+ $data = $this->Csv->read($this->data['Event']['file']['tmp_name']);
+ foreach ($data as $e) {
+ $events[] = $this->__mapEvent2($e);
+ }
+ }
+
+ foreach ($events as $e) {
+ $this->Event->create();
+ $this->Event->save($e);
+ }
+
+ $this->Session->setFlash('Import success');
+ $this->redirect(array('action' => 'index'));
+ }
+ }
+
+ function __mapEvent($event) {
+ $data = array('sharing' => 0, 'repeat' => 0);
+
+ if (isset($event['start_date'][0])) {
+ $event['start_date'] = $event['start_date'][0];
+ }
+ if (isset($event['end_date'][0])) {
+ $event['end_date'] = $event['end_date'][0];
+ }
+
+ $data['start'] = $event['start_date'];
+ $data['title'] = $event['summary'];
+
+ if (isset($event['duration'])) {
+ $offset = $this->__duration($event['duration']);
+ $data['end'] = date('Y-m-d H:i:s', strtotime($data['start'].' + '.$offset));
+ } elseif (isset($event['end_date'])) {
+ $data['end'] = $event['end_date'];
+ }
+ return $data;
+ }
+
+ function __mapEvent2($event) {
+ return array(
+ 'start' => date('Y-m-d H:i:s', strtotime(
+ $event['Start Date'] . ' ' . $event['Start Time']
+ )),
+ 'end' => date('Y-m-d H:i:s', strtotime(
+ $event['End Date'] . ' ' . $event['End Time']
+ )),
+ 'title' => $event['Subject'],
+ 'notes' => $event['Description'],
+ 'location' => $event['Location'],
+ 'repeat' => 0,
+ );
+ }
+
+ function export() {
+ // $this->RequestHandler->respondAs('text/calendar', array(
+ // 'attachment' => 'cal-export.ics'
+ // ));
+
+ $this->RequestHandler->respondAs('application/octet-stream', array(
+ 'attachment' => 'cal-export.csv'
+ ));
+
+ $data = array();
+ $events = $this->Event->find('all');
+
+ foreach ($events as $event) {
+ $data[] = array(
+ $event['title'],
+ date('m/d/Y', strtotime($event['Event']['start'])),
+ date('H:i:s A', strtotime($event['Event']['start'])),
+ date('m/d/Y', strtotime($event['Event']['end'])),
+ date('H:i:s A', strtotime($event['Event']['end'])),
+ 'False',
+ 'False',
+ date('m/d/Y', strtotime($event['Event']['start'])),
+ date('H:i:s A', strtotime($event['Event']['start'])),
+ '',
+ '',
+ '',
+ '',
+ '',
+ '',
+ $event['Event']['notes'],
+ $event['Event']['location'],
+ '',
+ 'Normal',
+ $event['Event']['sharing'] == 2 ? 'False' : 'True',
+ 'Normal',
+ 2
+ );
+ }
+
+ // iCal
+ /*foreach ($events as $event) {
+ $event = $event['Event'];
+ $tmp = array();
+ $tmp['DTSTART;TZID=US/Eastern'] = date('Ymd', strtotime($event['start'])).'T'.date('His', strtotime($event['start']));
+ $tmp['SUMMARY'] = $event['title'];
+ $tmp['DURATION'] = $this->ICal->__putDuration($event['start'], $event['end']);
+ $tmp['DESCRIPTION'] = r("\n", '\n', $event['notes']);
+ $tmp['DTSTAMP;TZID=US/Eastern'] = date('Ymd', strtotime($event['created'])).'T'.date('His', strtotime($event['created']));
+
+ if ($event['repeat'] && $event['repeat'] != 0) {
+ $tmp['RRULE'] = 'FREQ=' . ($event['repeat'] == 1 ? 'WEEKLY' : 'MONTHLY');
+ }
+ $data[] = $tmp;
+ }*/
+
+ $this->set(compact('data'));
+ $this->render('outlook_export', 'ajax');
+ }
+}
+
+?>
\ No newline at end of file
diff --git a/views/events/csv/index.ctp b/views/events/csv/index.ctp
new file mode 100755
index 0000000..bc1aea4
--- /dev/null
+++ b/views/events/csv/index.ctp
@@ -0,0 +1,8 @@
+"Subject","Start Date","Start Time","End Date","End Time","All day event","Reminder on/off","Reminder Date","Reminder Time","Meeting Organizer","Required Attendees","Optional Attendees","Meeting Resources","Billing Information","Categories","Description","Location","Mileage","Priority","Private","Sensitivity","Show time as"
+<?php
+
+foreach ($data as $item) {
+ e('"' . join('","', $item) . '"' . "\n");
+}
+
+?>
\ No newline at end of file
diff --git a/views/events/edit.ctp b/views/events/edit.ctp
new file mode 100755
index 0000000..f4ff753
--- /dev/null
+++ b/views/events/edit.ctp
@@ -0,0 +1,69 @@
+<div class="block">
+
+ <?php echo $form->create('Event', 'post', array('id' => 'EventFormData', 'onsubmit' => 'return true;')); ?>
+ <?php echo $html->hidden('Event/id', array('id' => 'EventId')); ?>
+
+ <table width='100%' border='0' cellpadding='4'>
+ <tr><td class="win_title" colspan='2' valign="top">
+ <div class='window_buttons'>
+ <?php echo $ajax->link('Save', '/calendar/save', array(
+ 'id' => 'eventFormSave',
+ 'complete' => 'Effect.SlideUp("eventForm");' . "\n" . 'Events.update(request.responseText);',
+ 'with' => 'Form.serialize("EventFormData")'
+ )); ?>
+ <?php echo $html->link('Cancel', 'javascript:void(0);', array(
+ 'id' => 'eventFormCancel', 'onclick' => "Effect.SlideUp('eventForm');"
+ )); ?>
+ </div>
+ <label>Event Edit Form</label>
+ </td></tr>
+ <tr><td class='labeltd'>
+ <label for="EventTitle">Title</label></td>
+ <td><?php echo $form->input('Event/title', array('class' => 'input_title')); ?><br />
+ </td></tr>
+ <tr><td class='labeltd'>
+ <label for="EventStartDate">Start</label>
+ </td><td>
+ <?php echo $html->input('Event/start_Date', array('class' => 'date')); ?>
+ <label for="EventStartTime" class="label_small">@</label>
+ <?php echo $html->input('Event/start_Time', array('class' => 'time')); ?><br />
+ </td></tr>
+ <tr><td class='labeltd'>
+ <label form="EventEndDate">End</label>
+ </td><td>
+ <?php echo $html->input('Event/end_Date', array('class' => 'date')); ?>
+ <label for="EventEndTime" class="label_small">@</label>
+ <?php echo $html->input('Event/end_Time', array('class' => 'time')); ?>
+ </tr><!--<tr><td class="labeltd">
+ <label form="EventRepeat">Repeat</label>
+ </td><td>
+ <?php echo $html->selectTag('Event/repeat', array('don\'t repeat', 'weekly', 'monthly'), null, array('id' => 'EventRepeat'), null, false); ?>
+ </tr>--><tr><td class="labeltd">
+ <label form="EventLocation">Location</label>
+ </td><td>
+ <?php echo $html->input('Event/location'); ?>
+ </tr><tr><td class="labeltd">
+ <label form="EventNotes">Notes</label>
+ </td><td>
+ <?php echo $html->textarea('Event/notes'); ?>
+ </td></tr>
+ <tr><td class='labeltd'>
+ <label form="EventEndDate">Sharing</label>
+ </td><td>
+ <?php echo $html->selectTag('Event/sharing', array('Private (only for me)', 'Shared (selected users)', 'Public (everyone can see)', 'Public Editable (everyone can update)'), null, null, null, false); ?>
+ <?php echo $javascript->event('EventSharing', 'change', '$F("EventSharing") == 1 ? $("EventShare").show() : $("EventShare").hide();'); ?>
+ </td></tr>
+ <tr><td colspan="2">
+ <div id="EventShare">
+ Share with users (Ctrl-click to select multiple):<br />
+ <?php echo $html->selectTag('SharedUsers/SharedUsers', $users, $this->data['SharedUsers'], array('id' => 'SharedUsers', 'multiple' => true), null, false); ?>
+
+ <?php if ($this->data['Event']['sharing'] != 1) { ?>
+ <?php echo $javascript->codeBlock('$("EventShare").hide();'); ?>
+ <?php } ?>
+ </div>
+ </td></tr>
+ </table>
+ </form>
+
+</div>
diff --git a/views/events/icaldbg.ctp b/views/events/icaldbg.ctp
new file mode 100755
index 0000000..764d124
--- /dev/null
+++ b/views/events/icaldbg.ctp
@@ -0,0 +1,19 @@
+<div id="eventForm">
+
+ <?php echo $html->formTag('/calendar/icaldbg', 'file'); ?>
+
+ <table style='width:100%;' border='0' cellpadding='10'>
+ <tr><td class='labeltd' style='text-align:left;background-color:#333;color:#ccc;padding:10px;' colspan='2'>
+ <label>Import Events</label>
+ <span style='float:right;'><?php echo $html->link('Cancel', '/', array('id' => 'eventFormCancel')); ?></span>
+ </td></tr>
+ <tr><td class='labeltd'>
+ <label for="EventTitle">File</label></td>
+ <td><?php echo $html->file('Event/file'); ?>
+ </td></tr>
+ <tr><td colspan='2' align='right'>
+ <?php echo $html->submit('Import'); ?>
+ </td></tr>
+ </table>
+ </form>
+</div>
\ No newline at end of file
diff --git a/views/events/ics/index.ctp b/views/events/ics/index.ctp
new file mode 100755
index 0000000..65a8e28
--- /dev/null
+++ b/views/events/ics/index.ctp
@@ -0,0 +1,37 @@
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//Sage Systems//Calendar 2.0//EN
+X-WR-TIMEZONE:US/Eastern
+CALSCALE:GREGORIAN
+METHOD:PUBLISH
+BEGIN:VTIMEZONE
+TZID:US/Eastern
+LAST-MODIFIED:20060515T203558Z
+BEGIN:DAYLIGHT
+DTSTART:20050403T070000
+TZOFFSETTO:-0400
+TZOFFSETFROM:+0000
+TZNAME:EDT
+END:DAYLIGHT
+BEGIN:STANDARD
+DTSTART:20051030T020000
+TZOFFSETTO:-0500
+TZOFFSETFROM:-0400
+TZNAME:EST
+END:STANDARD
+BEGIN:DAYLIGHT
+DTSTART:20060402T010000
+TZOFFSETTO:-0400
+TZOFFSETFROM:-0500
+TZNAME:EDT
+END:DAYLIGHT
+END:VTIMEZONE
+<?php foreach ($data as $item) { ?>
+BEGIN:VEVENT
+<?php foreach ($item as $key => $val) { ?>
+<?php echo $key; ?>:<?php echo $val; ?>
+
+<?php } ?>
+END:VEVENT
+<?php } ?>
+END:VCALENDAR
diff --git a/views/events/import.ctp b/views/events/import.ctp
new file mode 100755
index 0000000..bcb4e41
--- /dev/null
+++ b/views/events/import.ctp
@@ -0,0 +1,19 @@
+<?php echo $html->formTag('/calendar/import', 'file'); ?>
+
+ <table style='width:100%;' border='0' cellpadding='10'>
+ <tr><td class='win_title' colspan='2'>
+ <span class='window_buttons'>
+ <?php echo $html->link('Cancel', 'javascript:void(0)', array('id' => 'importFormCancel')); ?>
+ </span>
+ <label>Import Events</label>
+ </td></tr>
+ <tr><td class='labeltd'>
+ <label for="EventTitle">File</label></td>
+ <td><?php echo $html->file('Event/file'); ?>
+ </td></tr>
+ <tr><td colspan='2' align='right'>
+ <?php echo $html->submit('Import'); ?>
+ </td></tr>
+ </table>
+</form>
+<?php echo $javascript->event('$("importFormCancel")', 'click', 'Effect.SlideUp("eventForm");'); ?>
\ No newline at end of file
diff --git a/views/events/index.ctp b/views/events/index.ctp
new file mode 100755
index 0000000..aec6a10
--- /dev/null
+++ b/views/events/index.ctp
@@ -0,0 +1,126 @@
+<?php $javascript->cacheEvents(); ?>
+
+<?php if(!$isAjax) { ?>
+
+<div id="calLoader" style="display: none;">
+ <?php echo $html->image('cal/spinner.gif'); ?>
+</div>
+
+<div style="display: box;float:left;">
+<table id='tools'>
+ <tr>
+ <td>
+ <div class="tool_button" style="padding-left:5px;padding-right:5px;">
+ <?php echo $html->image('cal/spacer.gif', array(
+ 'alt' => 'spacer','height'=>'20','width'=>'5'
+ )); ?>
+ </div>
+ </td><td>
+ <div id="btnImport" class="tool_button">
+ <?php echo $html->image('cal/btn_import.gif', array('alt' => 'Import')); ?>
+ </div>
+ Import
+ </td><td>
+ <div id="btnExport" class="tool_button">
+ <?php echo $html->image('cal/btn_export.gif', array('alt' => 'Export')); ?>
+ </div>
+ Export
+ </td><td>
+ <div class="tool_button" style="padding-left:5px;padding-right:5px;">
+ <?php echo $html->image('cal/div.gif', array(
+ 'alt' => 'spacer','height' => '20', 'width' => '5'
+ )); ?>
+ </div>
+ </td><td>
+ <div id="btnPrint" class="tool_button">
+ <?php echo $html->image('cal/btn_print.gif', array('alt' => 'Print')); ?>
+ </div>
+ Print
+ </td><td>
+ <div class="tool_button" style="padding-left:5px;padding-right:5px;">
+ <?php echo $html->image('cal/spacer.gif', array(
+ 'alt' => 'spacer', 'height' => '20', 'width' => '5'
+ )); ?>
+ </div>
+ </td>
+ </tr>
+</table>
+</div>
+
+<div id="toolbar">
+
+ <div id="eventTools" style="display: none;">
+ <span id="btnEdit" class="tool_button">
+ <?php echo $html->image('cal/btn_edit.gif', array('alt' => 'Edit Event')); ?>
+ </span>
+ <span id="btnDelete" class="tool_button">
+ <?php echo $html->image('cal/btn_delete.gif', array('alt' => 'Delete Event')); ?>
+ </span>
+ </div>
+
+ <div id="dayTools" style="display: none;">
+ <span id="btnAdd" class="tool_button">
+ <?php echo $html->image('cal/btn_add.gif', array('alt' => 'Add Event')); ?>
+ </span>
+ <span id="btnZoom" class="tool_button">
+ <?php echo $html->image('cal/btn_zoom.gif', array('alt' => 'Day View')); ?>
+ </span>
+ </div>
+</div>
+
+<?php $javascript->event('$("btnEdit")', 'click', 'Events.edit(Calendar.Events.selected);'); ?>
+<?php $javascript->event('$("btnDelete")', 'click', 'Events.remove(Calendar.Events.selected);'); ?>
+<?php $javascript->event('$("btnAdd")', 'click', 'Events.add(Calendar.selected)'); ?>
+<?php $javascript->event('$("btnZoom")', 'click', 'Events.view(Calendar.selected);'); ?>
+<?php $javascript->event('$("btnImport")', 'click', $ajax->remoteFunction(array(
+ 'url' => '/calendar/import',
+ 'update' => 'eventForm',
+ 'complete' => 'Effect.SlideDown("eventForm");'
+))); ?>
+<?php $javascript->event('$("btnExport")', 'click', 'window.location = "'.$this->base.'/calendar/export";'); ?>
+<?php $javascript->event('$("btnPrint")', 'click', $ajax->remoteFunction(array(
+ 'url' => '/calendar/printerForm',
+ 'update' => 'eventForm',
+ 'complete' => 'Effect.SlideDown("eventForm");'
+))); ?>
+<div id="eventForm" style="display: none;"></div>
+<div id="log" style="display: none; line-height: 16px; position: absolute; left: 10px; top: 80%; font-size: 12px; width: 75%; height: 500px; overflow: auto; border: 1px solid #333333;"></div>
+
+<?php } ?>
+
+<?php if(!$isDay) { ?>
+ <?php $cal->init($month, $year); ?>
+ <?php echo $cal->draw('calendar', 'month', true, !$isAjax); ?>
+
+ <?php // Set up JavaScript bindings between Calendar object and UI ?>
+ <?php echo $javascript->codeBlock('Object.extend(Calendar, { base : "'.$this->base.'", year : '.$year.', month : '.$month.' });'); ?>
+ <?php echo $javascript->codeBlock('$("tools").show();'); ?>
+<?php } else {
+ echo $this->element('day');
+} ?>
+
+<?php echo $javascript->codeBlock('Calendar.bind("calendar");'); ?>
+<?php echo $javascript->object($events, true, 'events = ', ';'); ?>
+
+<?php echo $javascript->link('bindings'); ?>
+<script type="text/javascript">
+
+ Calendar.Events.click = Events.click;
+ Calendar.loading(true);
+ Calendar.Events.items = [];
+
+ z = 0;
+ while (typeof events[z] != 'undefined') {
+ Calendar.Events.add(events[z]);
+ z++;
+ }
+
+ Calendar.Events.select(null);
+ setTimeout('Calendar.loading(false);', 1);
+ Calendar.resize();
+
+ Event.observe(document, 'click', function(e) { Element.hide('toolbar'); }, true);
+ Element.hide('toolbar');
+</script>
+
+<?php echo $javascript->writeEvents(); ?>
\ No newline at end of file
diff --git a/views/events/json/index.ctp b/views/events/json/index.ctp
new file mode 100644
index 0000000..bab30ca
--- /dev/null
+++ b/views/events/json/index.ctp
@@ -0,0 +1 @@
+<?php echo $javascript->object($events); ?>
\ No newline at end of file
diff --git a/views/events/json/view.ctp b/views/events/json/view.ctp
new file mode 100644
index 0000000..d58581f
--- /dev/null
+++ b/views/events/json/view.ctp
@@ -0,0 +1 @@
+<?php echo $javascript->object($event); ?>
\ No newline at end of file
diff --git a/views/events/save.ctp b/views/events/save.ctp
new file mode 100755
index 0000000..192691d
--- /dev/null
+++ b/views/events/save.ctp
@@ -0,0 +1,9 @@
+<?php
+
+if (isset($data) && is_array($data)) {
+ e($javascript->object($data) . ' //'); // "//" for debug timestamp at the end
+} elseif (isset($id)) {
+ e($id);
+}
+
+?>
\ No newline at end of file
diff --git a/views/events/share.ctp b/views/events/share.ctp
new file mode 100755
index 0000000..2430480
--- /dev/null
+++ b/views/events/share.ctp
@@ -0,0 +1,14 @@
+<ul class="user_list">
+ <?php foreach($users as $user) { ?>
+ <li><?php echo $user['full_name']; ?></li>
+ <?php } ?>
+</ul>
+
+<div style="padding: 2px;">
+ Add a user <?php echo $html->selectTag('Event/share', $userList, null, array('id' => 'EventShare')); ?>
+ <?php echo $ajax->observeField('EventShare', array(
+ 'url' => '/calendar/share',
+ 'update' => 'Shared',
+ 'with' => 'Form.serialize("EventFormData")'
+ )); ?>
+</div>
\ No newline at end of file
diff --git a/views/layouts/json/default.ctp b/views/layouts/json/default.ctp
new file mode 100644
index 0000000..3f29013
--- /dev/null
+++ b/views/layouts/json/default.ctp
@@ -0,0 +1 @@
+<?php echo $content_for_layout; ?>
\ No newline at end of file
