/*jslint devel: true*/ /*global $, app, tizen, TemplateManager */ /** * @class Ui */ function Ui() { 'use strict'; } (function () { // strict mode wrapper 'use strict'; Ui.prototype = { templateManager: null, /** * UI module initialisation */ init: function UI_init(app) { this.app = app; this.templateManager = new TemplateManager(); $(document).ready(this.domInit.bind(this)); // init inner objects this.home.context = this; this.alarm.context = this; this.new_event.context = this; }, /** * When DOM is ready, initialise it */ domInit: function UI_domInit() { this.templateManager.loadToCache(['home', 'alarm', 'new_event', 'event', 'all_day_event'], this.initPages.bind(this)); // Disable text selection $.mobile.tizen.disableSelection(document); }, /** * Append pages to body and initialise them */ initPages: function UI_initPages() { var pages = []; pages.push(this.templateManager.get('home')); pages.push(this.templateManager.get('alarm')); pages.push(this.templateManager.get('new_event')); $('body').append(pages.join('')); this.fixContentHeight(); this.home.init(); this.alarm.init(); this.new_event.init(); document.addEventListener('webkitvisibilitychange', function (event) { $('input').blur(); $(".ui-popup").popup('close'); if ($.mobile.activePage.attr('id') !== "new_event") { if (document.webkitVisibilityState === 'visible') { app.loadEvents(); app.ui.checkTimeFormat(); if (app.eventId !== 0) { app.model.isEventExists(app.eventId, null, function () { $.mobile.changePage('#home'); }); } } } }); $(window).on('softkeyboardchange', function (e) { if (e.originalEvent.state === "off") { $("input:radio").checkboxradio("refresh"); } }); document.addEventListener('tizenhwkey', function(e) { if (e.keyName == "back") { if ($.mobile.activePage.attr('id') === 'home') { tizen.application.getCurrentApplication().exit(); } else { history.back(); } } }); $.mobile.changePage('#home', 'pop', false, true); }, /** * Contains method related to time format 12/24h * @namespace */ checkTimeFormat: function UI_checkTimeFormat () { var date = tizen.time.getDateFormat(true), time = tizen.time.getTimeFormat(); if (time === "h:m:s") { //(h:m:s) 24hours format and (ap h:m:s) 12hours format $("#demo-date-1, #demo-date-2").datetimepicker("option", "format", "MMM dd yyyy HH:mm"); } else { $("#demo-date-1, #demo-date-2").datetimepicker("option", "format", "MMM dd yyyy hh:mm tt"); } }, /** * Contains methods related to the #home page * @namespace */ home: { init: function UI_home_init() { var app = this.context.app, self = this, alarm = this.context.alarm; $('#exit_btn').on('tap', app.exit.bind(app)); $("input:radio").checkboxradio(); alarm.selectOption(); // buttons in the events list $('#events_list').on('tap', '.remove_event_btn', function () { var eventId = $(this).parents('.event').data('eventid'); app.model.deleteEvent(eventId); }); $('#events_list').on('click', '.edit_event_btn', function () { var eventId = $(this).parents('.event').data('eventid'), event = app.model.editEvent(eventId), field, date, duration, key, properties = ['summary', 'startDate', 'endDate']; app.ui.new_event.dateResetLock(true); app.eventId = eventId; properties.forEach(function(element){ if (event.hasOwnProperty(element)) { field = $('#new_event input[name="' + element + '"]'); if (field.length !== 0) { if (field.attr('type') === 'datetime') { date = self.TZD2Date(event[element]); field.datetimepicker('value', date); field.datetimepicker(); app.ui.new_event.setSelectAllDay(event.isAllDay); } else { field.val(event[element]); } } } }); $('#new_event h1').text('Edit Event'); if (event.alarms.length !== 0) { duration = app.retrieveTimeDurationInMinutes(event.alarms[0].before); } if(typeof duration == "undefined") { duration = -1; } alarm.selectOption(alarm.getValue(duration || 0)); $.mobile.changePage("#new_event"); // set select allDay property app.ui.new_event.setSelectAllDay(event.isAllDay); }); $('#newEventBtn').on('tap', function () { app.ui.new_event.dateResetLock(false); app.eventId = 0; $("#demo-date-1, #demo-date-2").datetimepicker(); $("#demo-date-1, #demo-date-2").datetimepicker(new Date()); // workaround - if just inietied once agan, datepickers remembers the date $('#new_event h1').text('New Event'); $('#title').val(''); app.ui.new_event.setSelectAllDay(false); alarm.selectOption(); }); this.loadEvents(); }, TZD2Date: function (tzdate) { return new Date( tzdate.getFullYear(), tzdate.getMonth(), tzdate.getDate(), tzdate.getHours(), tzdate.getMinutes(), tzdate.getSeconds(), tzdate.getMilliseconds() ); }, /** * Get start date value from the form (#demo-date-1 field) * * @returns {string} */ getStartDate: function UI_home_getStartDate() { var startDate = $('#demo-date-1').attr('data-date'); return startDate; }, /** * Get info if event is allDay event * * @returns {boolean} */ getAllDayInfo: function UI_home_getAllDayInfo() { var isAllDay = $('select#allDay').val() == '1' ? true : false; return isAllDay; }, /** * Get end date value from the form (#demo-date-2 field) * * @returns {string} */ getEndDate: function UI_home_getEndDate() { var endDate = $('#demo-date-2').attr('data-date'); return endDate; }, /** * Get the title from the form (#title field) * * @returns {string} */ getTitle: function UI_home_getTitle() { return $('#title').val(); }, /** * Get the description from the form (#des field) * * @returns {string} */ getDescription: function UI_home_getDescription() { return $('#des').val(); }, /** * Get the location from the form (#location field) * * @returns {string} */ getLocation: function UI_home_getLocation() { return $('#location').val(); }, /** * Wrapper for app.loadEvents * @param {Object} e event * @param {Date} date selected date */ loadEvents: function UI_home_loadEvents(e, date) { this.context.app.loadEvents(date); }, /** * Returns text for separating list items with events * Skips repeated values * * @param {Object} event * @returns {string} */ getSeparatorText: function UI_home_getSeparatorText(event) { var previous = ''; // redefine itself this.getSeparatorText = function (event) { if (event === undefined) { previous = ''; return undefined; } var startDate = event.startDate, str = this.formatDate(startDate); if (previous === str) { return ''; // skip it - already returned } previous = str; // store in the closure for future comparison return str; }; return this.getSeparatorText(event); }, formatDate: function UI_home_formatDate(date) { var monthNames = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ]; this.formatDate = function UI_home_formatDate(date) { return date.getDate() + ". " + monthNames[date.getMonth()] + " " + date.getFullYear(); }; return this.formatDate(date); }, /** * Format hour * @param {TZDate} date * @returns {string} */ formatHour: function UI_home_formatHour(date) { return date.getHours() + ':' + this.pad(date.getMinutes()); }, /** * Zero-pads a positive number to 2 digits */ pad: function UI_home_pad(number) { return number < 10 ? '0' + number : number; }, /** * Creates HTML representing the given array of alarms * * @param {Alarm[]} alarms * @returns {string} */ getAlarmsHtml: function UI_home_getAlarmsHtml(alarms) { var alarm = '', j, len; len = alarms.length; if (len) { alarm += '

'; for (j = 0; j < len; j += 1) { alarm += alarms[j].before.length; alarm += ' ' + alarms[j].before.unit; } alarm += '

'; } return alarm; }, /** * Load the events into the #event_popup. * * Callback function for app.loadEvents. * @param {Array} events */ onEventSearchSuccess: function UI_home_onEventSearchSuccess(events) { var i = 0, j = 0, str = "", event, alarm = '', dividerText = '', templateParameters = {}, tmplName; // content str = ''; for (i = 0; i < events.length; i += 1) { event = events[i]; dividerText = this.getSeparatorText(event); if (dividerText) { str += '
  • ' + dividerText + '
  • '; } alarm = this.getAlarmsHtml(event.alarms); templateParameters = { uid: event.id.uid, startDate: this.formatHour(event.startDate), endDate: this.formatHour(event.endDate), summary: event.summary || '[No title]', location: event.location, description: event.description, alarm: alarm }; tmplName = event.isAllDay ? 'all_day_event' : 'event'; str += this.context.templateManager.get(tmplName, templateParameters); } this.getSeparatorText(); // clear the separator state $('#events_list ul').html(str); $('#events_list ul').listview(); $('#events_list ul').data('listview').refresh(); $('#events_list ul input.edit_event_btn').button(); $('#events_list ul input.remove_event_btn').button(); }, /** * Error handler for event search */ onEventSearchError: function UI_home_onEventSearchError() { console.error("event search error"); } }, /** * Contains methods related to the #alarm page * @namespace */ alarm: { init: function UI_alarm_init() { var self = this; $("input.customDuration").on('change', function () { var tmpChecked, val = $("input.customDuration").val() || 0; $.each($('#new_alarm input:radio'), function () { tmpChecked = $(this).val(); if ( tmpChecked === val) { $(this).attr('checked', true).checkboxradio('refresh'); } else { $(this).attr('checked', false).checkboxradio('refresh'); } }); self.getValue(val); app.switchAlarm(); self.updateDurationLabel(); }); $('#new_alarm input:radio').on('change', function () { $("input.customDuration").val($(this).val()); self.getValue($(this).val()); app.switchAlarm(); self.updateDurationLabel(); }); }, /** * Read alarm duration from the UI * * @returns {int} Alarm duration in minutes */ selectOption: function (val) { if(typeof val == "undefined") { val = 0; } $.each($('#new_alarm input:radio'), function () { $(this).attr('checked', parseInt($(this).val(), 10) === val) .checkboxradio('refresh'); }); this.getValue(val); app.switchAlarm(); this.updateDurationLabel(); }, getDuration: function UI_alarm_getDuration() { var self = this; var radiobutton = null, inputValue = $("input.customDuration").val(); radiobutton = $('#new_alarm :jqmData(role=controlgroup) input:radio[checked]'); return inputValue; }, getValue: function (duration) { $("input.customDuration").val(parseInt(duration, 10)); return duration; }, /** * Read and set alarm duration label * * @returns {string} Label */ updateDurationLabel: function () { var label = parseInt($("input.customDuration").val(), 10); if (label === -1) { label = "Off"; } else { label += " minutes before"; } $("label.customDuration span.customDurationSpan").text(label); $('#alarm').text(label); return label; } }, /** * Contains methods related to the new event page * @namespace */ new_event: { init: function UI_newEvent_init() { var app = this.context.app, self = this; $("#demo-date-1, #demo-date-2").datetimepicker(); app.ui.checkTimeFormat(); $("#demo-date-1").bind("date-changed", function UI_newEvent_onDateChanged(e, newStartDate) { var startOptions = $(this).data('datetimepicker').options, that = $(this), oldStartDate, today = new Date(), setter1 = $("#demo-date-1").datetimepicker("value"), setter2 = $("#demo-date-2").datetimepicker("value"); if ( setter1 > setter2 ) { $("#demo-date-2").datetimepicker("value", newStartDate); } // get the old date oldStartDate = startOptions.oldDate; startOptions.oldDate = newStartDate; if (!oldStartDate) { console.warn('date-changed handler: old date empty'); return; } else if (newStartDate - today < 0) { that.datetimepicker('value', today); that.datetimepicker(); newStartDate = today; } }); $("#demo-date-2").bind("date-changed", function (e, newEndDate) { var endOptions = $(this).data('datetimepicker').options, that = $(this), f = Math.floor, setter1 = $("#demo-date-1").datetimepicker("value"), startDate = $("#demo-date-1").data('datetimepicker').options.date; if ((f(new Date(newEndDate).getTime()/1000/60) - f(new Date(startDate).getTime()/1000/60)) < 0) { alert('End date cannot be earlier than initial date'); setTimeout(function() { that.datetimepicker('value', startDate); }, 200); } else { endOptions.oldDate = newEndDate; } }); $("select#allDay").bind("change", function () { $('.ui-datefield-hour, .ui-datefield-min, .ui-datefield-period, span[data-pat=":"]') .toggle(); }); $('#new_event').on('pageshow', function UI_newEvent_onPageShow(event) { var startOptions = $("#demo-date-1").data('datetimepicker').options, date2 = $("#demo-date-2"), tmpDate; // get the start date tmpDate = new Date(startOptions.date.getTime()); // store it for future use startOptions.oldDate = new Date(startOptions.date.getTime()); if (self.dateResetLock() !== true) { if (typeof date2.datetimepicker === 'function') { // set end date date2.datetimepicker('value', tmpDate); } else { console.warn('pageinit: cant set end time'); } } $('#add-event-btn').removeClass('disabled'); // enable OK button }); $('#switch-1').on('changed', app.switchFullDay.bind(app)); $('#add-event-btn').on('tap', this.addEvent.bind(this)); $('#add-event-btn').on('tap', function (e) { var setter1 = $("#demo-date-1").datetimepicker("value"), today = new Date(); if ( setter1 > today ) { $('#add-event-btn').addClass('disabled'); } $('#add-event-btn').removeClass('disabled'); }); $('#add-event-cancel-btn').on('tap', this.cancel.bind(this)); //alarm selection confirm $('#add-alarm').on('tap', app.switchAlarm.bind(app)); // go to alarm selection $('#add_alarm').on('tap', function (e) { e.preventDefault(); self.dateResetLock(true); $.mobile.changePage('#new_alarm'); }); $('#new_event').on('tap', '[data-role="content"]', function (e) { e.stopPropagation(); }); }, /** * Select an alarm value */ switchAlarm: function Ui_newEvent_switchAlarm(e) { this.dateResetLock(false); this.context.app.switchAlarm(e); }, /** * Set reset lock (true - locked, false - unlocked) * If no or undefined value given, return the current value * @param {bool} value * @returns {bool} */ dateResetLock: function Ui_newEvent_dateResetLock(value) { if (value === undefined) { return $("#demo-date-2").data('resetLock'); } $("#demo-date-2").data('resetLock', value); return value; }, setSelectAllDay: function (value) { var select = $('select#allDay'); if (value) { select[0].selectedIndex = 1; $('.ui-datefield-hour, .ui-datefield-min, .ui-datefield-period, span[data-pat=":"]') .hide(); } else { select[0].selectedIndex = 0; $('.ui-datefield-hour, .ui-datefield-min, .ui-datefield-period, span[data-pat=":"]') .show(); } try { select.slider("refresh"); } catch (e){} }, addEvent: function Ui_newEvent_addEvent(e) { e.preventDefault(); e.stopPropagation(); var button = $('#add-event-btn'); this.dateResetLock(false); if (!button.hasClass('disabled')) { button.addClass('disabled'); if (app.eventId === 0) { this.context.app.addEvent(e, function(){ $.mobile.changePage('#home'); }); } else { this.context.app.updateEvent(e, function(){ $.mobile.changePage('#home'); }); } } }, cancel: function Ui_newEvent_cancel(e) { e.preventDefault(); e.stopPropagation(); $.mobile.changePage('#home'); this.dateResetLock(false); } }, fixContentHeight: function Ui_fixContentHeight() { var contentHeight = screen.availHeight - $('div[data-role="header"]').outerHeight() - $('div[data-role="footer"]').outerHeight(); $('div[data-role="content"]').css('height', contentHeight); } }; }());