Task: Event Manager
This task, based on the EventManager sample delivered with the Tizen SDK, demonstrates how you can use the Calendar API to manage calendar events. For more information on the sample functionality and creating the sample with the full source code, see EventManager.
This task consists of the following parts:
- Defining the Application Layout defines how to create the application screens.
- Initializing the Application defines how to initialize the application.
- Managing Calendar Events defines how to add, modify, delete, and set alarms for calendar events.
- Filtering Calendar Events defines how to retrieve specific events.
This sample is a fully functional application for managing the device calendar. The user can add, modify, retrieve, and remove events, set the event type and duration, and set alarms for the events.
Defining the Application Layout
The EventManager sample application layout uses the template manager based on the MVC (Model-View-Controller) architecture, and consists of 3 screens: the main screen displays the events list, the New event screen allows adding and editing events, and the Set alarm screen enables setting an alarm for an event.
The following figure shows the main screens of the application.
Figure: EventManager screens
Using the Template Manager
The template manager enables the HTML output generation to be divided into 3 parts.
- app.ui.templateManager.js Source File
-
The template manager loads the template files into the cache.
loadToCache: function TemplateManager_loadToCache(tplNames, onSuccess) { var self = this, cachedTemplates = 0, tplName, tplPath; if ($.isArray(tplNames)) { $.each(tplNames, function(index, fileName) { if (self.cache[fileName] === undefined) { tplName = [fileName, app.config.get('templateExtension')].join(''); tplPath = [app.config.get('templateDir'), tplName].join('/'); $.ajax( { url: tplPath, cache: true, dataType: 'html', async: true, success: function(data) { cachedTemplates += 1; self.cache[fileName] = data; if (cachedTemplates >= tplNames.length && typeof onSuccess === 'function') { onSuccess(); } }, error: function(jqXHR, textStatus, errorThrown) { /* Error handling */ } }); } else { cachedTemplates += 1; if (cachedTemplates >= tplNames.length && typeof onSuccess === 'function') { onSuccess(); } } }); } }
-
Next, the template manager returns the template HTML content from the cache.
get: function TemplateManager_get(tplName, tplParams) { if (this.cache[tplName] !== undefined) { return this.getCompleted(this.cache[tplName], tplParams); } return ''; }
-
Finally, the template manager returns the completed template using the specified parameters.
getCompleted: function TemplateManager_getCompleted(tplHtml, tplParams) { var tplParam, replaceRegExp; for (tplParam in tplParams) { if (tplParams.hasOwnProperty(tplParam)) { replaceRegExp = new RegExp(['%', tplParam, '%'].join(''), 'g'); tplHtml = tplHtml.replace(replaceRegExp, tplParams[tplParam]); } } return tplHtml; }
-
Defining the Main Screen
- templates/home.tpl Source File
-
The main screen displays a list of calendar events. The header section of the screen is defined within a <div> element whose data-role attribute is set to header. The header section determines the title of the screen.
<div data-role="page" id="home" data-add-back-btn="false"> <!--Header section--> <div data-role="header"> <h1>Event manager</h1> </div>
-
The actual content section of the screen is defined within a <div> element whose data-role attribute is set to content. The content section of the main screen contains a list component (in mobile or wearable applications) displaying the elements as defined in the templates/event.tpl and templates/all_day_event.tpl files.
<!--Content section--> <div data-role="content"> <div> <center> <input type="date" id="homeDateFilter"/> </center> </div> <div id="events_list"> <ul data-role="listview" data-inset="true"></ul> </div> </div>
-
The footer section of the screen is defined within a <div> element whose data-role attribute is set to footer. The footer section contains a tab bar with buttons for adding an event and closing the application.
<!--Footer section--> <div data-role="footer" data-position="fixed"> <div data-role="tabbar" data-style="tabbar" > <ul> <li><a href="#new_event" id="newEventBtn">Add New Event</a></li> <li><a href="javascript:void(0)" id="exit_btn">Exit</a></li> </ul> </div> </div> </div>
-
- templates/event.tpl Source File
Each event is displayed in the list showing a summary text, and a start and end date, and 2 buttons (in mobile or wearable applications).
<li class="event" data-eventid="%uid%"> <div class="ui-li-aside ui-li-desc"> <span class="description">%summary|escape%</span><br/> <div class="green_dot"></div><small>%startDateTime%</small><br/> <div class="red_dot"></div><small>%endDateTime%</small><br/> </div> <div class="editEvent"> <form> <input type="button" class="edit_event_btn" data-inline="true" value="edit"/> </form> </div> <div class="deleteEvent"> <form> <input type="button" class="remove_event_btn" data-inline="true" value="delete"/> </form> </div> </li>
Defining the New Event Screen
- templates/new_event.tpl Source File
The New event screen contains UI components for setting the event title, type, start and end date, and an alarm for the event. The footer section of the screen contains a tab bar with buttons for saving the event information, or deleting it.
<!--New event screen layout--> <div data-role="page" id="new_event"> <!--Header section--> <div data-role="header" data-position="fixed"> <h1>New event</h1> </div> <!--Content section--> <div data-role="content"> <fieldset> <label for="title">Title</label> <div><input type="text" name="summary" id="title" maxlength="9"/></div> <label for="dataAllDay">Type</label> <div id="dataAllDay" data-role="dataAllDay"> <span class="allDaySwitcher"> <select id="allDay" data-role="slider"> <option value="1">All day</option> <option value="0">Period</option> </select> </div> <label for="demo-date-1">Start</label> <div id="date-1"> <span class="ui-li-text-main"> <input type="datetime" name="startDate" id="demo-date-1" data-format="MMM dd yyyy HH:mm"/> </span> </div> <label for="demo-date-2">End</label> <div id="date-2"> <span class="ui-li-text-main"> <input type="datetime" name="endDate" id="demo-date-2" data-format="MMM dd yyyy HH:mm"/> </span> </div> <label for="alarm">Alarm</label> <div> <span id="alarm">0 minutes before</span> <a id="add_alarm" data-inline="true" data-role="button">change</a> </div> </fieldset> </div> <!--Footer section--> <div data-role="footer" data-position="fixed"> <div data-role="tabbar" data-style="tabbar"> <ul> <li><a id="add-event-cancel-btn" data-inline="true">Cancel</a></li> <li><a id="add-event-btn" data-inline="true">OK</a></li> </ul> </div> </div> </div>
Defining the Set Alarm Screen
- templates/alarm.tpl Source File
The Set alarm screen contains radio buttons for defining the time of the alarm. The footer section of the screen contains a button for saving the alarm setting.
<!--Set alarm screen layout--> <div data-role="page" id="new_alarm" data-add-back-btn="false"> <!--Header section--> <div data-role="header" data-position="fixed"> <h1>Set alarm</h1> </div> <!--Content section--> <div data-role="content"> <input type="radio" name="radio-choice" id="radio-choice-0" value="-1" /> <label for="radio-choice-0">(Off)</label> <input type="radio" name="radio-choice" id="radio-choice-1" value="0" checked /> <label for="radio-choice-1">On time</label> <input type="radio" name="radio-choice" id="radio-choice-2" value="5" /> <label for="radio-choice-2">5 minutes before</label> <input type="radio" name="radio-choice" id="radio-choice-3" value="30" /> <label for="radio-choice-3">30 minutes before</label> <input type="radio" name="radio-choice" id="radio-choice-4" value="60" /> <label for="radio-choice-4">1 hour before</label> <input type="radio" class="customDuration" name="radio-choice" id="yes_1" value="Yes" > <label for="yes_1">custom time:</label> <span class="customDetails"> <input placeholder="00" class="customDuration" type="number" name="radio-choice" min="0" max="99" id="customDuration"/> minute(s) before </span> </div> <!--Footer section--> <div data-role="footer" data-position ="fixed"> <div data-role="tabbar" data-style="tabbar" > <ul> <li><a href="#new_event" id="add-alarm">Save</a></li> </ul> </div> </div> </div>
Initializing the Application
- config.xml Source File
The required privileges are declared in the config.xml file.
<!--Configuration file content--> <widget ...> <!--Other configuration details--> <tizen:privilege name="http://tizen.org/privilege/application.launch"/> <tizen:privilege name="http://tizen.org/privilege/calendar.read"/> <tizen:privilege name="http://tizen.org/privilege/calendar.write"/> <tizen:privilege name="http://tizen.org/privilege/time"/> </widget>
Managing Calendar Events
This section builds upon the elements described in Adding Events to a Calendar and Managing a Single Calendar Event.
The calendar event management functionality is implemented in the js/app.model.js file.
- Accessing Events
To access events, retrieve the default calendar using the getDefaultCalendar() method.
getCalendar: function Model_getCalendar() { return tizen.calendar.getDefaultCalendar("EVENT"); },
- Creating a New Calendar Event
Use the addEventToDefaultCalendar() method to add a new event to the calendar.
addEventToDefaultCalendar: function Model_addEventToDefaultCalendar(calendarItemInit) { var calendar = null, event = null; calendar = this.getCalendar(); event = new tizen.CalendarEvent(calendarItemInit); .add(event); },
- Modifying a Calendar Event
Use the get() method to get the calendar, and use the update() method to save the changed values to the calendar.
updateEvent: function Model_updateEvent(event_id, new_values) { var myCalendar = this.getCalendar(), new_event, prop, event = myCalendar.get(new tizen.CalendarEventId(event_id)); for (prop in new_values) { if (new_values.hasOwnProperty(prop)) { event[prop] = new_values[prop]; /* Copy the new values into the event object */ } } myCalendar.update(event, false); },
- Deleting Calendar Event
Use the remove() method to delete an event, and update the event list using the loadEvents() method.
deleteEvent: function Model_deleteEvent(event_id) { var myCalendar = this.getCalendar(); myCalendar.remove(new tizen.CalendarEventId(event_id)); this.app.loadEvents(); },
Filtering Calendar Events
The calendar event filtering functionality is implemented in the js/app.model.js file.
- Creating a Filter
Use the getStartDateFilter() method to create a filter for a given date. The filter includes events starting on the specified date or before, and ending on the specified date or later. It also includes all-day events for the specified date.
getStartDateFilter: function Model_getStartDateFilter(date) { var today = new tizen.TZDate(date.getFullYear(), date.getMonth(), date.getDate()), tomorrow = new tizen.TZDate(date.getFullYear(), date.getMonth(), date.getDate()+1); return new tizen.CompositeFilter("UNION", [ new tizen.CompositeFilter("INTERSECTION", [ new tizen.AttributeFilter("isAllDay", "EXACTLY", false), new tizen.AttributeRangeFilter("startDate", null, tomorrow), new tizen.AttributeRangeFilter("endDate", today, null) ]), new tizen.CompositeFilter("INTERSECTION", [ new tizen.AttributeFilter("isAllDay", "EXACTLY", true), new tizen.AttributeRangeFilter("startDate", tomorrow, tomorrow), ]) ]); },
- Retrieving Filtered Events
Use the find() method with the composite filter created above to retrieve filtered events from the calendar.
getEventsFromDefaultCalendar: function Model_getEventsFromDefaultCalendar(date, onSuccess, onError) { var calendar = null, filter = null; calendar = this.getCalendar(); filter = this.getStartDateFilter(app.homeDateFilter); calendar.find(onSuccess, onError, filter); },