Updated application sources
[apps/web/sample/ExercisePlanner.git] / project / js / app.ui.js
1 /*
2  *      Copyright 2013  Samsung Electronics Co., Ltd
3  *
4  *      Licensed under the Flora License, Version 1.1 (the "License");
5  *      you may not use this file except in compliance with the License.
6  *      You may obtain a copy of the License at
7  *
8  *              http://floralicense.org/license/
9  *
10  *      Unless required by applicable law or agreed to in writing, software
11  *      distributed under the License is distributed on an "AS IS" BASIS,
12  *      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *      See the License for the specific language governing permissions and
14  *      limitations under the License.
15  */
16
17 /*jslint devel: true*/
18 /*global $, app, tizen, TemplateManager, window */
19
20 /**
21  * @class Ui
22  */
23
24 function Ui() {
25     'use strict';
26 }
27
28 (function () { // strict mode wrapper
29     'use strict';
30     Ui.prototype = {
31
32         templateManager: null,
33
34         /**
35          * UI module initialisation
36          */
37         init: function UI_init(app, exerciseId) {
38             this.app = app;
39             this.currentExercise = this.app.getExercise('id', exerciseId);
40             this.templateManager = new TemplateManager();
41             $(document).ready(this.domInit.bind(this));
42
43             // init inner objects
44             this.home.context = this;
45             this.new_exercise.context = this;
46             this.notification.context = this;
47         },
48
49         /**
50          * When DOM is ready, initialise it
51          */
52         domInit: function UI_domInit() {
53             this.templateManager.loadToCache(
54                 [
55                     'home',
56                     'exercise',
57                     'new_exercise',
58                     'notification',
59                     'exerciseNotification'
60                 ],
61                 this.initPages.bind(this)
62             );
63             // Disable text selection
64             $.mobile.tizen.disableSelection(document);
65         },
66
67         /**
68          * Append pages to body and initialise them
69          */
70         initPages: function UI_initPages() {
71             var pages = [];
72
73             pages.push(this.templateManager.get('home'));
74             pages.push(this.templateManager.get('new_exercise'));
75             pages.push(this.templateManager.get('notification'));
76
77             $('body').append(pages.join(''));
78
79             this.home.init();
80             this.new_exercise.init();
81             this.notification.init();
82
83             window.addEventListener('tizenhwkey', function (e) {
84                 var activePageId = $.mobile.activePage.attr('id');
85                 if (e.keyName === 'back') {
86                     if (activePageId === 'home') {
87                         app.exit();
88                     } else if (activePageId === 'notification') {
89                         app.exit();
90                     } else if (activePageId === 'new_exercise') {
91                         $.mobile.changePage('#home');
92                     } else {
93                         history.back();
94                     }
95                 }
96             });
97
98             $('input[type=checkbox]').change(function () {
99                 $('#name').blur();
100             });
101
102             $('#name').on('keyup change', function () {
103                 var checked = $('#newExerciseDays input:checkbox:checked');
104                 if (checked.length > 0) {
105                     $('#add-exercise-btn').removeClass('ui-disabled');
106                 } else {
107                     $('#add-exercise-btn').addClass('ui-disabled');
108                 }
109             });
110
111             if (this.currentExercise) {
112                 // app run from alarm
113                 $.mobile.changePage('#notification', 'pop', false, true);
114             } else {
115                 $.mobile.changePage('#home', 'pop', false, true);
116             }
117         },
118
119         /**
120          * Contains methods related to the home page
121          * @namespace
122          */
123         home: {
124
125             /**
126              * Initialize home page
127              */
128             init: function UI_home_init() {
129                 this.addEvents();
130             },
131
132             /**
133              * Bind events to the home page
134              */
135             addEvents: function () {
136                 var self = this;
137
138                 $('#home').on('pagebeforeshow', function () {
139                     this.displayList();
140                 }.bind(this));
141
142                 $('.removeExercise').live('click', function () {
143                     var exerciseId = $(this).data('exerciseid');
144                     app.ui.popup('Are you sure?', {
145                         'No': function () {
146                             $('#popup').popup('close');
147                         },
148                         'Yes': function () {
149                             self.context.app.removeExercise(
150                                 exerciseId,
151                                 self.displayList.bind(self)
152                             );
153                             $('#popup').popup('close');
154                         }
155                     });
156                 });
157             },
158
159             /**
160              * Build exercises HTML list and adds it to page
161              * @param {Array|undefined} exercises list
162              */
163             displayList: function (exercises) {
164                 var len, list = '', exercise;
165                 exercises = exercises || this.context.app.getAllExercises();
166                 len = exercises.length - 1;
167                 while (len >= 0) {
168                     exercise = $.extend({}, exercises[len]); // copy object
169                     exercise.startTime = exercise
170                         .startTime
171                         .match(/.+T([0-9]+\:[0-9]+)\:[0-9]+/)[1];
172                     list += this.context.templateManager.get(
173                         'exercise',
174                         exercise
175                     );
176                     len -= 1;
177                 }
178                 $('#alarms_list').html(list);
179             }
180
181         },
182
183         /**
184          * Contains methods related to the new exercise page
185          * @namespace
186          */
187         new_exercise: {
188
189             /**
190              * Initialize new exercise page
191              */
192             init: function () {
193                 this.addEvents();
194             },
195
196             /**
197              * Bind events to new exercise page
198              */
199             addEvents: function () {
200                 var self = this,
201                     numberOfChecked = 0,
202                     isName = false,
203                     toggleSaveButton = function () {
204                         var $button = $('#add-exercise-btn');
205                         if (numberOfChecked && isName) {
206                             $button.removeClass('ui-disabled');
207                         } else {
208                             $button.addClass('ui-disabled');
209                         }
210                     };
211
212                 $('#new_exercise').on('pagebeforeshow', function () {
213                     var checked, len;
214                     // clear everything
215                     numberOfChecked = 0;
216                     isName = false;
217                     $('#name').val('');
218                     $('#comment').val('');
219                     checked = $('#newExerciseDays input:checkbox:checked');
220                     len = checked.length - 1;
221                     while (len >= 0) {
222                         $(checked[len])
223                             .attr('checked', false)
224                             .data('checkboxradio')
225                             .refresh();
226                         len -= 1;
227                     }
228                     toggleSaveButton();
229                 });
230
231                 // bind buttons
232                 $('#add-exercise-btn').on('click', function () {
233                     var exercise = {}, days, len;
234
235                     days = $('#newExerciseDays input:checkbox:checked');
236                     len = days.length - 1;
237                     exercise.days = [];
238                     while (len >= 0) {
239                         exercise.days.unshift($(days[len]).data('day'));
240                         len -= 1;
241                     }
242
243                     exercise.name = $('#name').val();
244                     exercise.startTime = $('#startTime')
245                         .datetimepicker('value');
246                     exercise.comment = $('#comment').val();
247
248                     this.app.addExercise(exercise, function () {
249                         $.mobile.changePage('#home');
250                     });
251
252                 }.bind(this.context));
253
254                 $('#add-exercise-cancel-btn').on('click', function () {
255                     history.back();
256                 });
257
258                 $('#name').on('focusout', function () {
259                     isName = ($(this).val().length > 0);
260                     toggleSaveButton();
261                 });
262
263                 $('#newExerciseDays [type=checkbox]').on('change', function () {
264                     if ($(this).is(':checked')) {
265                         numberOfChecked += 1;
266                     } else {
267                         numberOfChecked -= 1;
268                     }
269
270                     toggleSaveButton();
271                 });
272             }
273
274         },
275
276         /**
277          * Contains methods related to the notification page
278          * @namespace
279          */
280         notification: {
281
282             /**
283              * Initialize notification page
284              */
285             init: function () {
286                 this.addEvents();
287             },
288
289             /**
290              * Bind events to notification page
291              */
292             addEvents: function () {
293                 $('#notification').on('pagebeforeshow', function () {
294                     var exercise, html;
295                     // copy object
296                     exercise = $.extend({}, this.context.currentExercise);
297                     exercise.startTime = exercise
298                         .startTime
299                         .match(/.+T([0-9]+\:[0-9]+)\:[0-9]+/)[1];
300                     html = this.context.templateManager.get(
301                         'exerciseNotification',
302                         exercise
303                     );
304                     $('.notificationContainer').html(html);
305                 }.bind(this));
306
307                 $('.exit').on('click', function () {
308                     app.exit();
309                 });
310             }
311
312         }
313
314     };
315
316     /**
317      * Create and display popup widget
318      * @param {String} text information
319      * @param {Object} buttons template object
320      */
321     Ui.prototype.popup = function (text, buttons) {
322         var i, popup = $('#popup'), popupNumber = Object.keys(buttons).length;
323
324         // if the popup HTML wasn't initialized
325         // init it
326         if (!popup.hasClass('ui-popup')) {
327             popup.popup();
328         }
329
330         // if buttons template wasn't add,
331         // use default template
332         if (!buttons) {
333             buttons = {
334                 'OK': function () {
335                     $('#popup').popup('close');
336                 }
337             };
338         }
339
340         // clear popup
341         $('.ui-popup-button-bg', popup).empty();
342
343         popup[0].className = popup[0]
344             .className
345             .replace(/\bcenter_basic.*?\b/g, '');
346         popup.addClass('center_basic_' + popupNumber + 'btn');
347
348         // adds buttons to popup HTML element
349         for (i in buttons) {
350             if (buttons.hasOwnProperty(i)) {
351                 if (buttons[i]) {
352                     $('<a/>').text(i).attr({
353                         'data-role': 'button',
354                         'data-inline': 'true'
355                     }).bind('click', buttons[i]).appendTo(
356                         $('.ui-popup-button-bg', popup)
357                     );
358                 }
359             }
360         }
361         // adds text to popup HTML element
362         $('.ui-popup-text p', popup).text(text);
363
364         popup.trigger('create');
365         // open popup
366         popup.popup('open', {
367             positionTo: 'window'
368         });
369     };
370
371 }());