/** * @class SimpleTasks.controller.Tasks * @extends Ext.app.Controller */ Ext.define('SimpleTasks.controller.Tasks', { extend: 'Ext.app.Controller', models: ['Task'], stores: ['Tasks'], views: [ 'tasks.Grid', 'tasks.Form', 'tasks.EditWindow', 'tasks.DefaultTimeWindow', 'tasks.ReminderWindow', 'tasks.ContextMenu' ], refs: [ { ref: 'listTree', selector: 'listTree' }, { ref: 'taskForm', selector: 'taskForm' }, { ref: 'taskGrid', selector: 'taskGrid' }, { ref: 'tasksToolbar', selector: 'tasksToolbar' }, { ref: 'taskEditWindow', selector: 'taskEditWindow', xtype: 'taskEditWindow', autoCreate: true }, { ref: 'defaultTimeWindow', selector: 'defaultTimeWindow', xtype: 'defaultTimeWindow', autoCreate: true }, { ref: 'reminderWindow', selector: 'reminderWindow', xtype: 'reminderWindow', forceCreate: true }, { ref: 'contextMenu', selector: 'tasksContextMenu', xtype: 'tasksContextMenu', autoCreate: true } ], init: function() { var me = this; me.control( { 'taskForm textfield': { specialkey: me.handleSpecialKey }, '[iconCls=tasks-new]': { click: me.focusTaskForm }, '#delete-task-btn': { click: me.handleDeleteClick }, '#delete-task-item': { click: me.handleDeleteClick }, '#mark-complete-item': { click: me.markComplete }, '#mark-complete-btn': { click: me.markComplete }, '#mark-active-item': { click: me.markActive }, '#mark-active-btn': { click: me.markActive }, '#show-all-btn': { click: me.filterAll }, '#show-active-btn': { click: me.filterActive }, '#show-complete-btn': { click: me.filterComplete }, '#edit-task-item': { click: me.handleEditItemClick }, 'taskGrid': { recordedit: me.updateTask, deleteclick: me.handleDeleteIconClick, editclick: me.handleEditIconClick, reminderselect: me.setReminder, itemmouseenter: me.showActions, itemmouseleave: me.hideActions, selectionchange: me.toggleButtons, columnresize: me.syncTaskFormFieldWidth, itemcontextmenu: me.showContextMenu }, 'tasksToolbar': { afterrender: me.initShowAll }, 'taskEditWindow [name=has_reminder]': { change: me.toggleReminderFields }, '#cancel-task-edit-btn': { click: me.hideEditWindow }, '#save-task-edit-btn': { click: me.handleSaveTaskClick }, 'taskEditWindow [name=reminder_date]': { change: me.syncReminderField }, 'taskEditWindow [name=reminder_time]': { change: me.syncReminderField }, '#toggle-complete-btn': { click: me.toggleCompleteField }, '#delete-task-window-btn': { click: me.deleteTaskAndCloseEditWindow }, 'defaultTimeWindow [name=default_time]': { }, '#cancel-default-time-edit-btn': { click: me.hideDefaultTimeWindow }, '#save-default-time-btn': { click: me.saveDefaultTime }, '[cls=snooze-btn]': { click: me.snooze }, '[cls=dismiss-reminder-btn]': { click: me.dismissReminder } } ); me.initReminderInterval(); }, /** * Handles a "specialkey" event on an field on the task form. * Creates a new task if the enter key is pressed. * @param {Ext.form.field.Text} field * @param {Ext.EventObject} e */ handleSpecialKey: function(field, e) { if(e.getKey() === e.ENTER) { this.newTask(); } }, /** * Creates a new task based on the data currently contained in the task form. * Saves the new task to the server and adds it to the task list view. */ newTask: function() { var me = this, form = me.getTaskForm(), basicForm = form.getForm(), formEl = form.getEl(), titleField = form.getForm().findField('title'), task = Ext.create('SimpleTasks.model.Task'); // require title field to have a value if(!titleField.getValue()) { return; } // update the new task record with the data from the form. basicForm.updateRecord(task); // try to blur all of this form's items to make sure that the user can't type into a field while saving form.items.each(function(item) { var inputEl = item.getEl().down('input') if(inputEl) { inputEl.blur(); } }); // mask the form element while saving formEl.mask('saving . . .'); // save the task to the server task.save({ success: function(task, operation) { me.getTasksStore().add(task); me.refreshFiltersAndCount(); me.getTasksStore().sort(); titleField.reset(); titleField.focus(); formEl.unmask(); }, failure: function(task, operation) { var error = operation.getError(), msg = Ext.isObject(error) ? error.status + ' ' + error.statusText : error; Ext.MessageBox.show({ title: 'Add Task Failed', msg: msg, icon: Ext.Msg.ERROR, buttons: Ext.Msg.OK }); formEl.unmask(); } }); }, /** * Handles the task list's "recordedit" event. * Updates the task on the server whenever a task is updated using the task grid's cell editor * @param {SimpleTasks.model.Task} task The task record that was edited */ updateTask: function(task) { var me = this; if(task.modified.done === false) { task.set('reminder', null); } task.save({ success: function(task, operation) { me.refreshFiltersAndCount(); me.getTasksStore().sort(); }, failure: function(task, operation) { var error = operation.getError(), msg = Ext.isObject(error) ? error.status + ' ' + error.statusText : error; Ext.MessageBox.show({ title: 'Update Task Failed', msg: msg, icon: Ext.Msg.ERROR, buttons: Ext.Msg.OK }); } }); }, /** * Handles a click on a delete icon in the task grid. * @param {Ext.grid.View} view * @param {Number} rowIndex * @param {Number} colIndex * @param {Ext.grid.column.Action} column * @param {EventObject} e */ handleDeleteIconClick: function(view, rowIndex, colIndex, column, e) { this.deleteTask(this.getTasksStore().getAt(rowIndex)); }, /** * Handles a click on the "delete task" button or context menu item * @param {Ext.button.Button} button * @param {Ext.EventObject} e */ handleDeleteClick: function(button, e) { this.deleteTask(this.getTaskGrid().getSelectionModel().getSelection()[0]); }, /** * Deletes the task from the server and updates the view. * @param {SimpleTasks.model.Task} task * @param {Function} successCallback A function to call after the task has been deleted successfully */ deleteTask: function(task, successCallback) { var me = this; Ext.Msg.show({ title: 'Delete Task?', msg: 'Are you sure you want to delete this task?', buttons: Ext.Msg.YESNO, fn: function(response) { if(response === 'yes') { task.destroy({ success: function(task, operation) { me.getTasksStore().remove(task); me.refreshFiltersAndCount(); if(successCallback) { successCallback(); } }, failure: function(task, operation) { var error = operation.getError(), msg = Ext.isObject(error) ? error.status + ' ' + error.statusText : error; Ext.MessageBox.show({ title: 'Delete Task Failed', msg: msg, icon: Ext.Msg.ERROR, buttons: Ext.Msg.OK }); } }); } } }); }, /** * Refreshes the task grid's list filter, and the task counts in the list tree */ refreshFiltersAndCount: function() { // refresh the task filters this.getTaskGrid().refreshFilters(); // refresh the lists list view so that the task counts will be correct this.getListTree().refreshView(); }, /** * Handles a click on the "Edit" context menu item * @param {Ext.menu.Item} item * @param {EventObject} e */ handleEditItemClick: function(item, e) { this.showEditWindow(this.getContextMenu().getTask()); }, /** * Handles a click on the "Edit Task" action column * @param {Ext.grid.View} view * @param {Number} rowIndex * @param {Number} colIndex * @param {Ext.grid.column.Action} column * @param {EventObject} e */ handleEditIconClick: function(view, rowIndex, colIndex, column, e) { this.showEditWindow(view.getRecord(view.findTargetByEvent(e))); }, /** * Handles the task grid's "selectionchange" event. * Disables or enables the task-related toolbar buttons depending on whether or not there is a selection. * @param {Ext.selection.RowModel} selModel * @param {SimpleTasks.model.Task[]} tasks */ toggleButtons: function(selModel, tasks) { var deleteTaskBtn = Ext.getCmp('delete-task-btn'), markCompleteBtn = Ext.getCmp('mark-complete-btn'), markActiveBtn = Ext.getCmp('mark-active-btn'); if(tasks.length === 0) { deleteTaskBtn.disable(); markCompleteBtn.disable(); markActiveBtn.disable(); } else { deleteTaskBtn.enable(); markCompleteBtn.enable(); markActiveBtn.enable(); } }, /** * Handles a click on the "New Task" button or context menu item * focuses the title field on the new task form * @param {Ext.Component} component * @param {Ext.EventObject} e */ focusTaskForm: function(component, e) { this.getTaskForm().query('[name=title]')[0].focus(); }, /** * Handles a click on the "Mark Complete" button or menu item * Sets the selected task's "done" field to true * @param {Ext.Component} component * @param {Ext.EventObject} e */ markComplete: function(component, e) { var contextMenu = this.getContextMenu(), task = contextMenu.isVisible() ? contextMenu.getTask() : this.getTaskGrid().getSelectionModel().getSelection()[0]; task.set('done', true); task.set('reminder', null); task.save({ failure: function(task, operation) { var error = operation.getError(), msg = Ext.isObject(error) ? error.status + ' ' + error.statusText : error; Ext.MessageBox.show({ title: 'Mark Complete Failed', msg: msg, icon: Ext.Msg.ERROR, buttons: Ext.Msg.OK }); } }); this.refreshFiltersAndCount(); }, /** * Handles a click on the "Mark Active" button * Sets the selected task's "done" field to false * @param {Ext.button.Button} button * @param {Ext.EventObject} e */ markActive: function(button, e) { var contextMenu = this.getContextMenu(), task = contextMenu.isVisible() ? contextMenu.getTask() : this.getTaskGrid().getSelectionModel().getSelection()[0]; task.set('done', false); task.save({ failure: function(task, operation) { var error = operation.getError(), msg = Ext.isObject(error) ? error.status + ' ' + error.statusText : error; Ext.MessageBox.show({ title: 'Mark Active Failed', msg: msg, icon: Ext.Msg.ERROR, buttons: Ext.Msg.OK }); } }); this.refreshFiltersAndCount(); }, /** * Handles the task grid columnresize event. * Synchronizes the width the column's associated form field with the width of the column * @param {Ext.grid.header.Container} headerContainer * @param {Ext.column.Column} column * @param {Number} width The new column width */ syncTaskFormFieldWidth: function(headerContainer, column, width) { var field = this.getTaskForm().query('[name=' + column.dataIndex + ']')[0]; if (field) { field.setWidth(width - 5); } }, /** * Handles a click on the "Show All" button. Removes any filter on the done field so that all tasks will be displayed * @param {Ext.button.Button} button * @param {Ext.EventObject} e */ filterAll: function(button, e) { var tasksStore = this.getTasksStore(), filters = tasksStore.filters.getRange(0, tasksStore.filters.getCount() - 1), filterCount = filters.length, i = 0; if(button.pressed) { tasksStore.clearFilter(); for(; i < filterCount; i++) { if(filters[i].property === 'done') { filters.splice(i, 1); filterCount --; } } tasksStore.filter(filters); } else { button.toggle(); } }, /** * Handles a click on the "Show Active" button. Filters tasks by done = false * @param {Ext.button.Button} button * @param {Ext.EventObject} e */ filterActive: function(button, e) { var tasksStore = this.getTasksStore(), filters = tasksStore.filters.getRange(0, tasksStore.filters.getCount() - 1), filterCount = filters.length, i = 0; if(button.pressed) { tasksStore.clearFilter(); for(; i < filterCount; i++) { if(filters[i].property === 'done') { filters.splice(i, 1); filterCount --; } } filters.push({ property: 'done', value: false }); this.getTasksStore().filter(filters); } else { button.toggle(); } }, /** * Handles a click on the "Show Complete" button. Filters tasks by done = true. * @param {Ext.button.Button} button * @param {Ext.EventObject} e */ filterComplete: function(button, e) { var tasksStore = this.getTasksStore(), filters = tasksStore.filters.getRange(0, tasksStore.filters.getCount() - 1), filterCount = filters.length, i = 0; if(button.pressed) { tasksStore.clearFilter(); for(; i < filterCount; i++) { if(filters[i].property === 'done') { filters.splice(i, 1); filterCount --; } } filters.push({ property: 'done', value: true }); this.getTasksStore().filter(filters); } else { button.toggle(); } }, /** * Handles the tasks toolbar's render event * Initializes the "Show All" Button to the pressed state * @param {SimpleTasks.view.Toolbar} toolbar */ initShowAll: function(toolbar) { toolbar.getComponent('show-all-btn').toggle(); }, /** * Handles a mouseenter event on a task grid item. * Shows the item's action icons. * @param {Ext.grid.View} view * @param {SimpleTasks.model.Task} task * @param {HTMLElement} node * @param {Number} rowIndex * @param {Ext.EventObject} e */ showActions: function(view, task, node, rowIndex, e) { var icons = Ext.DomQuery.select('.x-action-col-icon', node); Ext.each(icons, function(icon){ Ext.get(icon).removeCls('x-hidden'); }); }, /** * Handles a mouseleave event on a task grid item. * Hides the item's action icons. * @param {Ext.grid.View} view * @param {SimpleTasks.model.Task} task * @param {HTMLElement} node * @param {Number} rowIndex * @param {Ext.EventObject} e */ hideActions: function(view, task, node, rowIndex, e) { var icons = Ext.DomQuery.select('.x-action-col-icon', node); Ext.each(icons, function(icon){ Ext.get(icon).addCls('x-hidden'); }); }, /** * Handles the task grid's itemcontextmenu event * Shows the task context menu. * @param {Ext.grid.View} view * @param {SimpleTasks.model.Task} task * @param {HTMLElement} node * @param {Number} rowIndex * @param {Ext.EventObject} e */ showContextMenu: function(view, task, node, rowIndex, e) { var contextMenu = this.getContextMenu(), markCompleteItem = Ext.getCmp('mark-complete-item'), markActiveItem = Ext.getCmp('mark-active-item'); if(task.get('done')) { markCompleteItem.hide(); markActiveItem.show(); } else { markCompleteItem.show(); markActiveItem.hide(); } contextMenu.setTask(task); contextMenu.showAt(e.getX(), e.getY()); e.preventDefault(); }, /** * Shows the "Edit Task" window * @param {SimpleTasks.model.Task} task the task to edit */ showEditWindow: function(task) { var me = this, taskEditWindow = me.getTaskEditWindow(), form = taskEditWindow.down('form').getForm(), reminderCheckbox = form.findField('has_reminder'), dateField = form.findField('reminder_date'), timeField = form.findField('reminder_time'), reminder = task.get('reminder'); // Set the tasks title as the title of the edit window taskEditWindow.setTitle('Edit Task - ' + task.get('title')); // load the task data into the form taskEditWindow.down('form').loadRecord(task); // set the text of the toggle-complete button depending on the tasks "done" value Ext.getCmp('toggle-complete-btn').setText(task.get('done') ? 'Mark Active' : 'Mark Complete'); taskEditWindow.show(); if(task.get('reminder')) { // if the task already has a reminder set check the reminder checkbox and populate the reminder date and reminder time fields reminderCheckbox.setValue(true); dateField.setValue(Ext.Date.clearTime(reminder, true)); timeField.setValue(Ext.Date.format(reminder, timeField.format)); } else { // if the task does not have a reminder set uncheck the reminder checkbox and set the reminder date and time fields to null reminderCheckbox.setValue(false); dateField.setValue(null); timeField.setValue(null); } if(task.get('done')) { // if the task is done disable the reminder checkbox (reminders cannot be set on completed tasks) reminderCheckbox.disable(); } else { reminderCheckbox.enable(); } }, /** * Handles a click on the "Edit Task" window's cancel button * Hides the "Edit Task" window * @param {Ext.Button} button * @param {Ext.EventObject} e */ hideEditWindow: function(button, e) { this.getTaskEditWindow().close(); }, /** * Handles the change event on the task edit window's "has_reminder" checkbox * Toggles the visibility of the reminder date and time fields * @param {Ext.form.field.Checkbox} checkbox * @param {Boolean} newValue * @param {Boolean} oldValue */ toggleReminderFields: function(checkbox, newValue, oldValue) { var taskEditWindow = this.getTaskEditWindow(), windowEl = taskEditWindow.getEl(), form = taskEditWindow.down('form').getForm(), task = form.getRecord(), dateField = form.findField('reminder_date'), timeField = form.findField('reminder_time'), defaultTimeDate, defaultTimeMilliseconds; if(newValue) { // if the "has reminder" checkbox was checked windowEl.mask('loading'); // get the default reminder time from the server or cache this.getDefaultReminderTime(function(defaultTime) { // enable the date and time fields dateField.enable(); timeField.enable(); if(!dateField.getValue()) { // if the reminder date has not already been set, default the reminder date to the task's due date // or the current date if the task does not have a due date dateField.setValue(task.get('due') || Ext.Date.clearTime(new Date())); timeField.setValue(defaultTime); } // set the form's hidden reminder field by combining the reminder date and time fields defaultTimeDate = timeField.getValue(); defaultTimeMilliseconds = defaultTimeDate - Ext.Date.clearTime(defaultTimeDate, true); form.findField('reminder').setValue(new Date(dateField.getValue().getTime() + defaultTimeMilliseconds)); windowEl.unmask(); }); } else { // if the "has reminder" checkbox was unchecked // nullify the form's hidden reminder field and disable the reminder date and time fields form.findField('reminder').setValue(null); dateField.disable(); timeField.disable(); } }, /** * Handles a click on the "Task Edit" window's save button. * @param {Ext.button.Button} button * @param {Ext.EventObject} e */ handleSaveTaskClick: function(button, e) { this.saveEditWindow(); }, /** * Updates the task record with the form data from the edit window and saves the task to the server. */ saveEditWindow: function() { var taskEditWindow = this.getTaskEditWindow(), windowEl = taskEditWindow.getEl(), form = taskEditWindow.down('form').getForm(), task = form.getRecord(); if(form.isValid()) { windowEl.mask('saving'); form.updateRecord(task); if(task.modified.done === false) { task.set('reminder', null); } task.save({ success: function(task, operation) { windowEl.unmask(); taskEditWindow.close(); }, failure: function(task, operation) { var error = operation.getError(), msg = Ext.isObject(error) ? error.status + ' ' + error.statusText : error; Ext.MessageBox.show({ title: 'Edit Task Failed', msg: msg, icon: Ext.Msg.ERROR, buttons: Ext.Msg.OK }); windowEl.unmask(); } }) } else { Ext.Msg.alert('Invalid Data', 'Please correct form errors'); } }, /** * Syncronizes the value of the edit window's hidden reminder field whenever "reminder_date", or "reminder_time" is changed * @param {Ext.form.field.Picker} field the date or time picker * @param {Date} oldValue * @param {Date} newValue */ syncReminderField: function(field, oldValue, newValue) { var form = this.getTaskEditWindow().down('form').getForm(), reminderField = form.findField('reminder'), date = form.findField('reminder_date').getValue(), timeDate = form.findField('reminder_time').getValue(), time, reminderDate; if(date && timeDate) { time = timeDate - Ext.Date.clearTime(timeDate, true), reminderDate = new Date(date.getTime() + time); reminderField.setValue(reminderDate); } }, /** * Toggles the edit window's "done" field to true when the "Mark Complete" or "Mark Active" button on the edit window is clicked * @param {Ext.button.Button} button * @param {Ext.EventObject} e */ toggleCompleteField: function(button, e) { var taskEditWindow = this.getTaskEditWindow(), doneField = taskEditWindow.down('form').getForm().findField('done'); if(doneField.getValue() === 'true') { doneField.setValue(false); } else { doneField.setValue(true); } this.saveEditWindow(); }, /** * Handles a click on the "Delete" button on the edit window. * Deletes the task and closes the edit window * @param {Ext.button.Button} button * @param {Ext.EventObject} e */ deleteTaskAndCloseEditWindow: function(button, e) { var me = this, taskEditWindow = me.getTaskEditWindow(), task = taskEditWindow.down('form').getRecord(); me.deleteTask(task, function() { me.getTaskEditWindow().close(); }); }, /** * Handles the Task Grid's `reminderselect` event * Sets a task's reminder * @param {SimpleTasks.model.Task} task the underlying record of the row that was clicked to show the reminder menu * @param {String|Number} value The value that was selected */ setReminder: function(task, value) { var me = this, defaultTimeWindow = me.getDefaultTimeWindow(), defaultTimeField = defaultTimeWindow.down('form').getForm().findField('default_time'), defaultTimeDate, defaultTimeMilliseconds; me.getDefaultReminderTime(function(defaultTime) { if(value === 'set') { // if the user selected "Set Default Time", show the default time window. defaultTimeField.setValue(defaultTime); defaultTimeWindow.show(); } else { if(Ext.isNumber(value)) { // if the user selected a reminder time, set the reminder by adding the user selected value to the due date defaultTimeDate = Ext.Date.parse(defaultTime, defaultTimeField.format); defaultTimeMilliseconds = defaultTimeDate - Ext.Date.clearTime(defaultTimeDate, true); task.set('reminder', new Date(task.get('due').getTime() - (value * 86400000) + defaultTimeMilliseconds)); } else { // if the user selected "No Reminder" set the reminder field to null task.set('reminder', null); } task.save({ failure: function(task, operation) { var error = operation.getError(), msg = Ext.isObject(error) ? error.status + ' ' + error.statusText : error; Ext.MessageBox.show({ title: 'Set Reminder Failed', msg: msg, icon: Ext.Msg.ERROR, buttons: Ext.Msg.OK }); } }); } }); }, /** * Gets the default reminder time and passes it to the callback function. * Retrieves default reminder time from the server on the first call, then caches it for future calls. * @param {Function} callback */ getDefaultReminderTime: function(callback) { var me = this, defaultReminderTime; if(me.defaultReminderTime) { callback(me.defaultReminderTime); } else { me.defaultReminderTime = '8:00 AM'; // the default time if no value can be retrieved from storage if (SimpleTasksSettings.useLocalStorage) { defaultReminderTime = localStorage.getItem('SimpleTasks-defaultReminderTime'); if (defaultReminderTime) { me.defaultReminderTime = defaultReminderTime; } callback(me.defaultReminderTime); } else { Ext.Ajax.request({ url: 'php/config/read.php', params: { key: 'default.reminder.time' }, success: function(response, options) { var responseData = Ext.decode(response.responseText); if(responseData.success && responseData.value) { me.defaultReminderTime = responseData.value; } callback(me.defaultReminderTime); }, failure: function(response, options) { callback(me.defaultReminderTime); } }); } } }, /** * Hides the default reminder time window when the cancel button is clicked * @param {Ext.button.Button} button * @param {Ext.EventObject} e */ hideDefaultTimeWindow: function(button, e) { this.getDefaultTimeWindow().close(); }, /** * Saves the default reminder time to the server when the OK button is clicked * @param {Ext.button.Button} button * @param {Ext.EventObject} e */ saveDefaultTime: function(button, e) { var me = this, defaultTimeWindow = me.getDefaultTimeWindow(), windowEl = defaultTimeWindow.getEl(), time = defaultTimeWindow.down('form').getForm().findField('default_time').getRawValue(); if (SimpleTasksSettings.useLocalStorage) { localStorage.setItem('SimpleTasks-defaultReminderTime', time); me.defaultReminderTime = time; defaultTimeWindow.close(); } else { windowEl.mask('saving'); Ext.Ajax.request({ url: 'php/config/update.php', params: { key: 'default.reminder.time', value: time }, success: function(response, options) { var responseData = Ext.decode(response.responseText); if(responseData.success) { me.defaultReminderTime = time; defaultTimeWindow.close(); } else { Ext.MessageBox.show({ title: 'Set Default Time Failed', msg: responseData.message, icon: Ext.Msg.ERROR, buttons: Ext.Msg.OK }); } windowEl.unmask(); }, failure: function(response, options) { Ext.MessageBox.show({ title: 'Set Default Time Failed', msg: response.status + ' ' + response.statusText, icon: Ext.Msg.ERROR, buttons: Ext.Msg.OK }); windowEl.unmask(); } }); } }, /** * Initializes checking for tasks that have passed their reminder date at 10 second intervals. */ initReminderInterval: function() { var me = this, now, reminderDate; setInterval(function() { now = new Date(); me.getTasksStore().each(function(task) { reminderDate = task.get('reminder'); if(reminderDate && reminderDate < now && !task.get('done')) { me.showReminderWindow(task); } }); }, 10000); }, /** * Shows the reminder window for a given task * @param {SimpleTasks.model.Task} task */ showReminderWindow: function(task) { var reminderWindow = this.getReminderWindow(), reminderDetailsBox = reminderWindow.down('[cls=tasks-reminder-details]'), title = task.get('title'); task.set('reminder', null); task.save({ failure: function(task, operation) { var error = operation.getError(), msg = Ext.isObject(error) ? error.status + ' ' + error.statusText : error; Ext.MessageBox.show({ title: 'Clear Reminder Failed', msg: msg, icon: Ext.Msg.ERROR, buttons: Ext.Msg.OK }); } }); reminderWindow.setTask(task); reminderWindow.setTitle('Reminder - ' + title); reminderDetailsBox.update({ title: title, due: task.get('due') }); reminderWindow.show(); }, /** * Handles a click on the snooze button on the reminder window. * Sets the task's reminder date to the current date plus snooze time selected * @param {Ext.button.Button} button * @param {Ext.EventObject} e */ snooze: function(button, e) { var reminderWindow = button.findParentByType('window'), task = reminderWindow.getTask(), snoozeMilliseconds = reminderWindow.down('[name=snooze_time]').getValue() * 60000, reminderDate = new Date(new Date().getTime() + snoozeMilliseconds); task.set('reminder', reminderDate); task.save({ failure: function(task, operation) { var error = operation.getError(), msg = Ext.isObject(error) ? error.status + ' ' + error.statusText : error; Ext.MessageBox.show({ title: 'Set Reminder Failed', msg: msg, icon: Ext.Msg.ERROR, buttons: Ext.Msg.OK }); } }); reminderWindow.close(); }, /** * Handle's a click on the reminder window's dismiss button. * Hides the reminder window. * @param {Ext.button.Button} button * @param {Ext.EventObject} e */ dismissReminder: function(button, e) { button.findParentByType('window').close(); } });