2 /*global $, app, TemplateManager */
11 (function () { // strict mode wrapper
15 templateManager: null,
18 * UI module initialisation
20 init: function UI_init(app) {
22 this.templateManager = new TemplateManager();
23 $(document).ready(this.domInit.bind(this));
26 this.home.context = this;
27 this.alarm.context = this;
28 this.new_event.context = this;
32 * When DOM is ready, initialise it
34 domInit: function UI_domInit() {
35 this.templateManager.loadToCache(['home', 'alarm', 'new_event', 'event'], this.initPages.bind(this));
36 // Disable text selection
37 $.mobile.tizen.disableSelection(document);
41 * Append pages to body and initialise them
43 initPages: function UI_initPages() {
46 pages.push(this.templateManager.get('home'));
47 pages.push(this.templateManager.get('alarm'));
48 pages.push(this.templateManager.get('new_event'));
50 $('body').append(pages.join(''));
54 this.new_event.init();
56 $.mobile.changePage('#home', 'pop', false, true);
61 * Contains methods related to the #home page
65 init: function UI_home_init() {
66 var app = this.context.app, self = this, alarm = this.context.alarm;
68 $('#exit_btn').on('tap', app.exit.bind(app));
69 $("input:radio").checkboxradio();
72 // buttons in the events list
73 $('#events_list').on('tap', '.remove_event_btn', function () {
74 var eventId = $(this).parents('.event').data('eventid');
75 app.model.deleteEvent(eventId);
78 $('#events_list').on('click', '.edit_event_btn', function () {
79 var eventId = $(this).parents('.event').data('eventid'),
80 event = app.model.editEvent(eventId), field, date, duration, key;
82 app.ui.new_event.dateResetLock(true);
83 app.eventId = eventId;
85 if (event.hasOwnProperty(key)) {
86 field = $('#new_event input[name="' + key + '"]');
87 if (field.length !== 0) {
88 if (field.attr('type') === 'datetime') {
89 date = self.TZD2Date(event[key]);
90 field.datetimepicker('value', date);
92 field.val(event[key]);
98 $('#new_event h1').text('Edit Event');
99 $('#add_alarm').hide();
101 if (event.alarms.length !== 0) {
102 duration = event.alarms[0].before.length;
104 alarm.selectOption(alarm.getValue(duration || 0));
105 $.mobile.changePage("#new_event");
108 $('#newEventBtn').on('tap', function () {
109 app.ui.new_event.dateResetLock(false);
111 $('#new_event h1').text('New Event');
113 $('#add_alarm').css('display', 'inline-block');
114 alarm.selectOption();
120 TZD2Date: function (tzdate) {
122 tzdate.getFullYear(),
128 tzdate.getMilliseconds()
133 * Get start date value from the form (#demo-date-1 field)
137 getStartDate: function UI_home_getStartDate() {
138 var startDate = $('#demo-date-1').attr('data-date');
142 * Get end date value from the form (#demo-date-2 field)
146 getEndDate: function UI_home_getEndDate() {
147 var endDate = $('#demo-date-2').attr('data-date');
151 * Get the title from the form (#title field)
155 getTitle: function UI_home_getTitle() {
156 return $('#title').val();
159 * Get the description from the form (#des field)
163 getDescription: function UI_home_getDescription() {
164 return $('#des').val();
167 * Get the location from the form (#location field)
171 getLocation: function UI_home_getLocation() {
172 return $('#location').val();
175 * Wrapper for app.loadEvents
176 * @param {Object} e event
177 * @param {Date} date selected date
179 loadEvents: function UI_home_loadEvents(e, date) {
180 this.context.app.loadEvents(date);
184 * Returns text for separating list items with events
185 * Skips repeated values
187 * @param {Object} event
190 getSeparatorText: function UI_home_getSeparatorText(event) {
194 this.getSeparatorText = function (event) {
195 if (event === undefined) {
200 var startDate = event.startDate,
201 str = this.formatDate(startDate);
203 if (previous === str) {
204 return ''; // skip it - already returned
206 previous = str; // store in the closure for future comparison
211 return this.getSeparatorText(event);
214 formatDate: function UI_home_formatDate(date) {
216 "January", "February", "March", "April", "May", "June",
217 "July", "August", "September", "October", "November", "December" ];
219 this.formatDate = function UI_home_formatDate(date) {
220 return date.getDate() + ". " + monthNames[date.getMonth()] + " " + date.getFullYear();
222 return this.formatDate(date);
227 * @param {TZDate} date
230 formatHour: function UI_home_formatHour(date) {
231 return date.getHours() + ':' + this.pad(date.getMinutes());
235 * Zero-pads a positive number to 2 digits
237 pad: function UI_home_pad(number) {
238 return number < 10 ? '0' + number : number;
242 * Creates HTML representing the given array of alarms
244 * @param {Alarm[]} alarms
247 getAlarmsHtml: function UI_home_getAlarmsHtml(alarms) {
248 var alarm = '', j, len;
253 alarm += '<p class="ui-li-aside ui-li-desc"><img src="img/clock.png"/>';
255 for (j = 0; j < len; j += 1) {
256 alarm += alarms[j].before.length;
257 alarm += ' ' + alarms[j].before.unit;
264 * Load the events into the #event_popup.
266 * Callback function for app.loadEvents.
267 * @param {Array} events
269 onEventSearchSuccess: function UI_home_onEventSearchSuccess(events) {
275 templateParameters = {};
280 for (i = 0; i < events.length; i += 1) {
283 dividerText = this.getSeparatorText(event);
286 str += '<li data-role="list-divider">' + dividerText + '</li>';
289 alarm = this.getAlarmsHtml(event.alarms);
291 templateParameters = {
293 startDate: this.formatHour(event.startDate),
294 endDate: this.formatHour(event.endDate),
295 summary: event.summary || '[No title]',
296 location: event.location,
297 description: event.description,
301 str += this.context.templateManager.get('event', templateParameters);
304 this.getSeparatorText(); // clear the separator state
306 $('#events_list ul').html(str);
307 $('#events_list ul').listview();
308 $('#events_list ul').data('listview').refresh();
309 $('#events_list ul input.edit_event_btn').button();
310 $('#events_list ul input.remove_event_btn').button();
314 * Error handler for event search
316 onEventSearchError: function UI_home_onEventSearchError() {
317 console.error("event search error");
322 * Contains methods related to the #alarm page
326 init: function UI_alarm_init() {
329 * Read alarm duration from the UI
331 * @returns {int} Alarm duration in minutes
333 selectOption: function (val) {
335 $.each($('#new_alarm input:radio'), function () {
336 $(this).attr('checked', parseInt($(this).val(), 10) === val)
337 .checkboxradio('refresh');
339 this.updateDurationLabel();
342 getDuration: function UI_alarm_getDuration() {
346 radiobutton = $('#new_alarm :jqmData(role=controlgroup) input:radio[checked]');
348 radioValue = parseInt(radiobutton.val(), 10);
350 switch (radioValue) {
353 case 2: // 5 minutes before
355 case 3: // 30 minutes before
357 case 4: // 1 hour before
360 console.warn('Unexpected duration value');
364 getValue: function (duration) {
365 var table = {0: 1, 5: 2, 30: 3, 60: 4};
366 return table[duration];
370 * Read and set alarm duration label
372 * @returns {string} Label
374 updateDurationLabel: function () {
375 var label = $('#new_alarm input:radio[checked]').next().text();
376 $('#alarm').text(label);
382 * Contains methods related to the new event page
386 init: function UI_newEvent_init() {
387 var app = this.context.app,
389 $("#demo-date-1, #demo-date-2").datetimepicker();
390 $("#demo-date-1").bind("date-changed", function UI_newEvent_onDateChanged(e, newStartDate) {
391 var startOptions = $(this).data('datetimepicker').options,
392 endData = $("#demo-date-2").data('datetimepicker'),
393 endOptions = typeof endData === 'object' ? endData.options : null,
398 oldStartDate = startOptions.oldDate;
399 startOptions.oldDate = newStartDate;
402 console.warn('date-changed handler: old date empty');
406 // calculate time difference in minutes
407 diff = (newStartDate.getTime() - oldStartDate.getTime()) / 1000 / 60;
409 endDate = endOptions.date;
411 // move the end date by 'diff'
412 endDate.setMinutes(endDate.getMinutes() + diff);
414 $("#demo-date-2").datetimepicker('value', endDate);
417 $("#demo-date-2").bind("date-changed", function (e, newEndDate) {
418 var endOptions = $(this).data('datetimepicker').options,
420 stardDate = $("#demo-date-1").data('datetimepicker').options.date,
423 oldEndDate = endOptions.oldDate;
425 if (newEndDate - stardDate < 0) {
426 $("#date-2 .ui-datefield span").animationComplete(function () {
427 alert('End date cannot be earlier than initial date');
428 self.datetimepicker('value', oldEndDate);
429 self.datetimepicker();
432 endOptions.oldDate = newEndDate;
436 $('#new_event').on('pageshow', function UI_newEvent_onPageShow(event) {
437 var startOptions = $("#demo-date-1").data('datetimepicker').options,
438 date2 = $("#demo-date-2"),
440 // get the start date
441 tmpDate = new Date(startOptions.date.getTime());
443 // store it for future use
444 startOptions.oldDate = new Date(startOptions.date.getTime());
447 tmpDate.setHours(tmpDate.getHours() + 1);
448 if (self.dateResetLock() !== true) {
449 if (typeof date2.datetimepicker === 'function') {
451 date2.datetimepicker('value', tmpDate);
453 console.warn('pageinit: cant set end time');
458 $('#add-event-btn').removeClass('disabled');
461 $('#switch-1').bind('changed', app.switchFullDay.bind(app));
463 $('#add-event-btn').bind('tap', this.addEvent.bind(this));
465 $('#new-event-cancel-btn').bind('tap', this.cancel.bind(this));
467 //alarm selection confirm
468 $('#add-alarm').bind('tap', app.switchAlarm.bind(app));
470 // go to alarm selection
471 $('#add_alarm').bind('tap', this.dateResetLock.bind(this, true));
473 $('#new_event').on('tap', '[data-role="content"]', function (e) {
479 * Select an alarm value
481 switchAlarm: function Ui_newEvent_switchAlarm(e) {
482 console.log('Ui_newEvent_switchAlarm');
483 this.dateResetLock(false);
484 this.context.app.switchAlarm(e);
488 * Set reset lock (true - locked, false - unlocked)
489 * If no or undefined value given, return the current value
490 * @param {bool} value
493 dateResetLock: function Ui_newEvent_dateResetLock(value) {
494 if (value === undefined) {
495 return $("#demo-date-2").data('resetLock');
497 $("#demo-date-2").data('resetLock', value);
501 addEvent: function Ui_newEvent_addEvent(e) {
502 var button = $('#add-event-btn');
503 this.dateResetLock(false);
504 if (!button.hasClass('disabled')) {
505 button.addClass('disabled');
506 if (app.eventId === 0) {
507 this.context.app.addEvent(e);
509 this.context.app.updateEvent(e);
514 cancel: function Ui_newEvent_cancel(e) {
515 this.dateResetLock(false);