3b4be960d45cea7f4cdfbe283aa32f4c7ec280f8
[samples/web/EventManager.git] / js / app.ui.js
1 /*jslint devel: true*/
2 /*global $, TemplateManager */
3
4 /**
5  * @class Ui
6  */
7 function Ui() {
8     'use strict';
9 }
10
11 (function () { // strict mode wrapper
12     'use strict';
13     Ui.prototype = {
14
15         templateManager: null,
16
17         /**
18          * UI module initialisation
19          */
20         init: function UI_init(app) {
21             console.log('Ui.init');
22             this.app = app;
23             this.templateManager = new TemplateManager();
24             $(document).ready(this.domInit.bind(this));
25
26             // init inner objects
27             this.home.context = this;
28             this.alarm.context = this;
29             this.new_event.context = this;
30         },
31
32         /**
33          * When DOM is ready, initialise it
34          */
35         domInit: function UI_domInit() {
36             console.log("domInit()", this);
37
38             this.templateManager.loadToCache(['home', 'alarm', 'new_event', 'event'], this.initPages.bind(this));
39
40             // immediately load events for today
41             //self.app.loadEvents(new Date());
42
43         },
44
45         /**
46          * Append pages to body and initialise them
47          */
48         initPages: function UI_initPages() {
49             console.log('initPages');
50             var pages = [];
51
52             pages.push(this.templateManager.get('home'));
53             pages.push(this.templateManager.get('alarm'));
54             pages.push(this.templateManager.get('new_event'));
55
56             $('body').append(pages.join(''));
57
58             this.home.init();
59             this.alarm.init();
60             this.new_event.init();
61
62             console.log('changePage');
63             $.mobile.changePage('#home', 'pop', false, true);
64         },
65
66
67         /**
68          * Contains methods related to the #home page
69          * @namespace
70          */
71         home: {
72             init: function UI_home_init() {
73                 var app = this.context.app;
74
75                 $('#exit_btn').on('tap', app.exit.bind(app));
76
77 //                $('#date_search').bind("date-changed", this.loadEvents.bind(this));
78
79                 // buttons in the events list
80                 $('#events_list').on('tap', '.remove_event_btn', function () {
81                     var eventId = $(this).parents('.event').data('eventid');
82                     app.model.deleteEvent(eventId);
83                 });
84
85                 $('#newEventBtn').on('tap', function () {
86                                         $('#des').val('');
87                 });
88
89                 this.loadEvents();
90             },
91             /**
92              * Get start date value from the form (#demo-date-1 field)
93              *
94              * @returns {string}
95              */
96             getStartDate: function UI_home_getStartDate() {
97                                 var startDate = $('#demo-date-1').attr('data-date');
98                                 console.log('UI_home_getStartDate: ', startDate);
99                 return startDate;
100             },
101             /**
102              * Get end date value from the form (#demo-date-2 field)
103              *
104              * @returns {string}
105              */
106             getEndDate: function UI_home_getEndDate() {
107                                 var endDate = $('#demo-date-2').attr('data-date');
108                                 console.log('UI_home_getEndDate: ', endDate);
109                 return endDate;
110             },
111             /**
112              * Get the title from the form (#title field)
113              *
114              * @returns {string}
115              */
116             getTitle: function UI_home_getTitle() {
117                 return $('#title').val();
118             },
119             /**
120              * Get the description from the form (#des field)
121              *
122              * @returns {string}
123              */
124             getDescription: function UI_home_getDescription() {
125                 return $('#des').val();
126             },
127             /**
128              * Get the location from the form (#location field)
129              *
130              * @returns {string}
131              */
132             getLocation: function UI_home_getLocation() {
133                 return $('#location').val();
134             },
135             /**
136              * Wrapper for app.loadEvents
137              * @param {Object} e event
138              * @param {Date} date selected date
139              */
140             loadEvents: function UI_home_loadEvents(e, date) {
141 //                date = $(':jqmData(role="datetimepicker")').data('datetimepicker').options.date;
142                 console.log('Ui.loadEvents', this);
143                 this.context.app.loadEvents(date);
144             },
145
146                         /**
147                          * Returns text for separating list items with events
148                          * Skips repeated values
149                          *
150                          * @param {Object} event
151                          * @returns {string}
152                          */
153                         getSeparatorText: function UI_home_getSeparatorText(event) {
154                                 var previous = '';
155
156                                 // redefine itself
157                                 this.getSeparatorText = function (event) {
158                                         if (event === undefined) {
159                                                 previous = '';
160                                                 return undefined;
161                                         }
162
163                                         var startDate = event.startDate,
164                                                 str = this.formatDate(startDate);
165
166                                         if (previous === str) {
167                                                 return ''; // skip it - already returned
168                                         }
169                                         previous = str; // store in the closure for future comparison
170
171                                         return str;
172                                 };
173
174                                 return this.getSeparatorText(event);
175                         },
176
177                         formatDate: function UI_home_formatDate(date) {
178                                 var monthNames = [
179                                         "January", "February", "March", "April", "May", "June",
180                                         "July", "August", "September", "October", "November", "December" ];
181
182                                 this.formatDate = function UI_home_formatDate(date) {
183                                         return date.getDate() + ". " + monthNames[date.getMonth()] + " " + date.getFullYear();
184                                 };
185                                 return this.formatDate(date);
186                         },
187
188                         /**
189                          * Format hour
190                          * @param {TZDate} date
191                          * @returns {string}
192                          */
193                         formatHour: function UI_home_formatHour(date) {
194                                 return date.getHours() + ':' + this.pad(date.getMinutes());
195                         },
196
197                         /**
198                          * Zero-pads a positive number to 2 digits
199                          */
200                         pad: function UI_home_pad(number) {
201                                 return number < 10 ? '0' + number : number;
202                         },
203
204                         /**
205                          * Creates HTML representing the given array of alarms
206                          *
207                          * @param {Alarm[]} alarms
208                          * @returns {string}
209                          */
210                         getAlarmsHtml: function UI_home_getAlarmsHtml(alarms) {
211                                 var alarm = '', j, len;
212
213                                 len = alarms.length;
214
215                                 if (len) {
216                                         alarm += '<p class="ui-li-aside ui-li-desc"><img src="img/clock.png"/>';
217
218                                         for (j = 0; j < len; j += 1) {
219                                                 alarm += alarms[j].before.length;
220                                                 alarm += ' ' + alarms[j].before.unit;
221                                         }
222                                         alarm += '</p>';
223                                 }
224                                 return alarm;
225                         },
226             /**
227              * Load the events into the #event_popup.
228              *
229              * Callback function for app.loadEvents.
230              * @param {Array} events
231              */
232             onEventSearchSuccess: function UI_home_onEventSearchSuccess(events) {
233                 var i = 0, j = 0,
234                     str = "",
235                     event,
236                     alarm = '',
237                     dividerText = '',
238                     templateParameters = {},
239                     endDate = null;
240
241
242                 console.log('Ui.home.onEventSearchSuccess()', events);
243
244                 // content
245                 str = '';
246
247                 for (i = 0; i < events.length; i += 1) {
248                     event = events[i];
249
250                     dividerText = this.getSeparatorText(event);
251
252                     if (dividerText) {
253                         str += '<li data-role="list-divider">' + dividerText + '</li>';
254                     }
255
256                     alarm = this.getAlarmsHtml(event.alarms);
257
258                     endDate = event.startDate.addDuration(event.duration);
259
260                     console.log('[Event Loaded] Start Date:' + event.startDate);
261
262                     templateParameters = {
263                         uid: event.id.uid,
264                         startDate: this.formatHour(event.startDate),
265                         endDate: this.formatHour(endDate),
266                         summary: event.summary || '[No title]',
267                         location: event.location,
268                         description: event.description,
269                         alarm: alarm
270                     };
271
272                     str += this.context.templateManager.get('event', templateParameters);
273
274
275                 }
276                 this.getSeparatorText(); // clear the separator state
277
278                 $('#events_list ul').html(str);
279                 $('#events_list ul').listview();
280                 $('#events_list ul').data('listview').refresh();
281                 $('#events_list ul input.remove_event_btn').button();
282             },
283
284             /**
285              * Error handler for event search
286              */
287             onEventSearchError: function UI_home_onEventSearchError() {
288                 console.error("event search error");
289             }
290         },
291
292         /**
293          * Contains methods related to the #alarm page
294          * @namespace
295          */
296         alarm: {
297             init: function UI_alarm_init() {
298             },
299             /**
300              * Read alarm duration from the UI
301              *
302              * @returns {int} Alarm duration in minutes
303              */
304             getDuration: function UI_alarm_getDuration() {
305                 var radioValue = 0,
306                     radiobutton = null;
307
308                 radiobutton = $('#new_alarm :jqmData(role=controlgroup) input:radio[checked]');
309
310                 radioValue = parseInt(radiobutton.val(), 10);
311
312                 switch (radioValue) {
313                 case 1: // no alarm
314                     return 0;
315                 case 2: // 5 minutes before
316                     return 5;
317                 case 3: // 30 minutes before
318                     return 30;
319                 case 4: // 1 hour before
320                     return 60;
321                 default:
322                     console.warn('Unexpected value');
323                     return 0;
324                 }
325             }
326         },
327
328         /**
329          * Contains methods related to the new event page
330          * @namespace
331          */
332         new_event: {
333             init: function UI_newEvent_init() {
334                 var app = this.context.app;
335
336                                 $("#demo-date-1").bind("date-changed", function UI_newEvent_onDateChanged(e, newStartDate) {
337                                         var startOptions = $("#demo-date-1").data('datetimepicker').options,
338                                                 endData = $("#demo-date-2").data('datetimepicker'),
339                                                 endOptions = typeof endData === 'object' ? endData.options : null,
340                                                 oldStartDate,
341                                                 diff,
342                                                 endDate;
343                                         // get the old date
344                                         oldStartDate = startOptions.oldDate;
345                                         startOptions.oldDate = newStartDate;
346
347                                         if (!oldStartDate) {
348                                                 console.warn('date-changed handler: old date empty');
349                                                 return;
350                                         }
351
352                                         // calculate time difference in minutes
353                                         diff = (newStartDate.getTime() - oldStartDate.getTime()) / 1000 / 60;
354
355                                         endDate = endOptions.date;
356
357                                         // move the end date by 'diff'
358                                         endDate.setMinutes(endDate.getMinutes() + diff);
359
360                                         $("#demo-date-2").datetimepicker('value', endDate);
361                                 });
362
363                                 $('#new_event').on('pageshow', function UI_newEvent_onPageShow(event) {
364                                         var options = $("#demo-date-1").data('datetimepicker').options,
365                                                 tmpDate;
366                                         // get the start date
367                                         tmpDate = new Date(options.date.getTime());
368
369                                         // store it for future use
370                                         options.oldDate = new Date(options.date.getTime());
371
372                                         // add 1 hour
373                                         tmpDate.setHours(tmpDate.getHours() + 1);
374
375                                         if (typeof $("#demo-date-2").datetimepicker === 'function') {
376                                                 // set end date
377                                                 console.log('pageinit: set default end time' + tmpDate);
378                                                 $("#demo-date-2").datetimepicker('value', tmpDate);
379                                         } else {
380                                                 console.log('pageinit: cant set end time');
381                                         }
382                                 });
383
384                 $('#switch-1').bind('changed', app.switchFullDay.bind(app));
385
386                 $('#add-event-btn').bind('tap', app.addEvent.bind(app));
387
388                 $('#add-alarm').bind('tap', app.switchAlarm.bind(app));
389             }
390         }
391     };
392
393 }());