]> git.proxmox.com Git - extjs.git/blame - extjs/examples/classic/simple-tasks/app/controller/Tasks.js
add extjs 6.0.1 sources
[extjs.git] / extjs / examples / classic / simple-tasks / app / controller / Tasks.js
CommitLineData
6527f429
DM
1/**\r
2 * @class SimpleTasks.controller.Tasks\r
3 * @extends Ext.app.Controller\r
4 */\r
5Ext.define('SimpleTasks.controller.Tasks', {\r
6 extend: 'Ext.app.Controller',\r
7\r
8 models: ['Task'],\r
9 stores: ['Tasks'],\r
10\r
11 views: [\r
12 'tasks.Grid',\r
13 'tasks.Form',\r
14 'tasks.EditWindow',\r
15 'tasks.DefaultTimeWindow',\r
16 'tasks.ReminderWindow',\r
17 'tasks.ContextMenu'\r
18 ],\r
19\r
20 refs: [\r
21 {\r
22 ref: 'listTree',\r
23 selector: 'listTree'\r
24 },\r
25 {\r
26 ref: 'taskForm',\r
27 selector: 'taskForm'\r
28 },\r
29 {\r
30 ref: 'taskGrid',\r
31 selector: 'taskGrid'\r
32 },\r
33 {\r
34 ref: 'tasksToolbar',\r
35 selector: 'tasksToolbar'\r
36 },\r
37 {\r
38 ref: 'taskEditWindow',\r
39 selector: 'taskEditWindow',\r
40 xtype: 'taskEditWindow',\r
41 autoCreate: true\r
42 },\r
43 {\r
44 ref: 'defaultTimeWindow',\r
45 selector: 'defaultTimeWindow',\r
46 xtype: 'defaultTimeWindow',\r
47 autoCreate: true\r
48 },\r
49 {\r
50 ref: 'reminderWindow',\r
51 selector: 'reminderWindow',\r
52 xtype: 'reminderWindow',\r
53 forceCreate: true\r
54 },\r
55 {\r
56 ref: 'contextMenu',\r
57 selector: 'tasksContextMenu',\r
58 xtype: 'tasksContextMenu',\r
59 autoCreate: true\r
60 }\r
61 ],\r
62\r
63 init: function() {\r
64 var me = this;\r
65 me.control(\r
66 {\r
67 'taskForm textfield': {\r
68 specialkey: me.handleSpecialKey\r
69 },\r
70 '[iconCls=tasks-new]': {\r
71 click: me.focusTaskForm\r
72 },\r
73 '#delete-task-btn': {\r
74 click: me.handleDeleteClick\r
75 },\r
76 '#delete-task-item': {\r
77 click: me.handleDeleteClick\r
78 },\r
79 '#mark-complete-item': {\r
80 click: me.markComplete\r
81 },\r
82 '#mark-complete-btn': {\r
83 click: me.markComplete\r
84 },\r
85 '#mark-active-item': {\r
86 click: me.markActive\r
87 },\r
88 '#mark-active-btn': {\r
89 click: me.markActive\r
90 },\r
91 '#show-all-btn': {\r
92 click: me.filterAll\r
93 },\r
94 '#show-active-btn': {\r
95 click: me.filterActive\r
96 },\r
97 '#show-complete-btn': {\r
98 click: me.filterComplete\r
99 },\r
100 '#edit-task-item': {\r
101 click: me.handleEditItemClick\r
102 },\r
103 'taskGrid': {\r
104 recordedit: me.updateTask,\r
105 deleteclick: me.handleDeleteIconClick,\r
106 editclick: me.handleEditIconClick,\r
107 reminderselect: me.setReminder,\r
108 itemmouseenter: me.showActions,\r
109 itemmouseleave: me.hideActions,\r
110 selectionchange: me.toggleButtons,\r
111 columnresize: me.syncTaskFormFieldWidth,\r
112 itemcontextmenu: me.showContextMenu\r
113 },\r
114 'tasksToolbar': {\r
115 afterrender: me.initShowAll\r
116 },\r
117 'taskEditWindow [name=has_reminder]': {\r
118 change: me.toggleReminderFields\r
119 },\r
120 '#cancel-task-edit-btn': {\r
121 click: me.hideEditWindow\r
122 },\r
123 '#save-task-edit-btn': {\r
124 click: me.handleSaveTaskClick\r
125 },\r
126 'taskEditWindow [name=reminder_date]': {\r
127 change: me.syncReminderField\r
128 },\r
129 'taskEditWindow [name=reminder_time]': {\r
130 change: me.syncReminderField\r
131 },\r
132 '#toggle-complete-btn': {\r
133 click: me.toggleCompleteField\r
134 },\r
135 '#delete-task-window-btn': {\r
136 click: me.deleteTaskAndCloseEditWindow\r
137 },\r
138 'defaultTimeWindow [name=default_time]': {\r
139 \r
140 },\r
141 '#cancel-default-time-edit-btn': {\r
142 click: me.hideDefaultTimeWindow\r
143 },\r
144 '#save-default-time-btn': {\r
145 click: me.saveDefaultTime\r
146 },\r
147 '[cls=snooze-btn]': {\r
148 click: me.snooze\r
149 },\r
150 '[cls=dismiss-reminder-btn]': {\r
151 click: me.dismissReminder\r
152 }\r
153 }\r
154 );\r
155\r
156 me.initReminderInterval();\r
157 },\r
158\r
159 /**\r
160 * Handles a "specialkey" event on an field on the task form.\r
161 * Creates a new task if the enter key is pressed.\r
162 * @param {Ext.form.field.Text} field\r
163 * @param {Ext.EventObject} e\r
164 */\r
165 handleSpecialKey: function(field, e) {\r
166 if(e.getKey() === e.ENTER) {\r
167 this.newTask();\r
168 }\r
169 },\r
170\r
171 /**\r
172 * Creates a new task based on the data currently contained in the task form.\r
173 * Saves the new task to the server and adds it to the task list view.\r
174 */\r
175 newTask: function() {\r
176 var me = this,\r
177 form = me.getTaskForm(),\r
178 basicForm = form.getForm(),\r
179 formEl = form.getEl(),\r
180 titleField = form.getForm().findField('title'),\r
181 task = Ext.create('SimpleTasks.model.Task');\r
182\r
183 // require title field to have a value\r
184 if(!titleField.getValue()) {\r
185 return;\r
186 }\r
187\r
188 // update the new task record with the data from the form.\r
189 basicForm.updateRecord(task);\r
190\r
191 // try to blur all of this form's items to make sure that the user can't type into a field while saving\r
192 form.items.each(function(item) {\r
193 var inputEl = item.getEl().down('input');\r
194 if(inputEl) {\r
195 inputEl.blur();\r
196 }\r
197 });\r
198\r
199 // mask the form element while saving\r
200 formEl.mask('saving . . .');\r
201 // save the task to the server\r
202 task.save({\r
203 success: function(task, operation) {\r
204 me.getTasksStore().add(task);\r
205 me.refreshListTree();\r
206 me.getTasksStore().sort();\r
207 titleField.reset();\r
208 titleField.focus();\r
209 formEl.unmask();\r
210 },\r
211 failure: function(task, operation) {\r
212 var error = operation.getError(),\r
213 msg = Ext.isObject(error) ? error.status + ' ' + error.statusText : error;\r
214\r
215 Ext.MessageBox.show({\r
216 title: 'Add Task Failed',\r
217 msg: msg,\r
218 icon: Ext.Msg.ERROR,\r
219 buttons: Ext.Msg.OK\r
220 });\r
221 formEl.unmask();\r
222 }\r
223 });\r
224 },\r
225\r
226 /**\r
227 * Handles the task list's "recordedit" event.\r
228 * Updates the task on the server whenever a task is updated using the task grid's cell editor\r
229 * @param {SimpleTasks.model.Task} task The task record that was edited\r
230 */\r
231 updateTask: function(task) {\r
232 var me = this;\r
233\r
234 if (task.modified && task.modified.done === false) {\r
235 task.set('reminder', null);\r
236 }\r
237 task.save({\r
238 success: function(task, operation) {\r
239 me.refreshListTree();\r
240 me.getTasksStore().sort();\r
241 },\r
242 failure: function(task, operation) {\r
243 var error = operation.getError(),\r
244 msg = Ext.isObject(error) ? error.status + ' ' + error.statusText : error;\r
245\r
246 Ext.MessageBox.show({\r
247 title: 'Update Task Failed',\r
248 msg: msg,\r
249 icon: Ext.Msg.ERROR,\r
250 buttons: Ext.Msg.OK\r
251 });\r
252 }\r
253 });\r
254 },\r
255\r
256 /**\r
257 * Handles a click on a delete icon in the task grid.\r
258 * @param {Ext.grid.View} view\r
259 * @param {Number} rowIndex\r
260 * @param {Number} colIndex\r
261 * @param {Ext.grid.column.Action} column\r
262 * @param {EventObject} e\r
263 */\r
264 handleDeleteIconClick: function(view, rowIndex, colIndex, column, e) {\r
265 this.deleteTask(this.getTasksStore().getAt(rowIndex));\r
266 },\r
267\r
268 /**\r
269 * Handles a click on the "delete task" button or context menu item\r
270 * @param {Ext.button.Button} button\r
271 * @param {Ext.EventObject} e\r
272 */\r
273 handleDeleteClick: function(button, e) {\r
274 this.deleteTask(this.getTaskGrid().getSelectionModel().getSelection()[0]);\r
275 },\r
276\r
277 /**\r
278 * Deletes the task from the server and updates the view.\r
279 * @param {SimpleTasks.model.Task} task\r
280 * @param {Function} successCallback A function to call after the task has been deleted successfully\r
281 */\r
282 deleteTask: function(task, successCallback) {\r
283 var me = this;\r
284 \r
285 Ext.Msg.show({\r
286 title: 'Delete Task?',\r
287 msg: 'Are you sure you want to delete this task?',\r
288 buttons: Ext.Msg.YESNO,\r
289 fn: function(response) {\r
290 if(response === 'yes') {\r
291 task.erase({\r
292 success: function(task, operation) {\r
293 me.getTasksStore().remove(task);\r
294 me.refreshListTree();\r
295 if(successCallback) {\r
296 successCallback();\r
297 }\r
298 },\r
299 failure: function(task, operation) {\r
300 var error = operation.getError(),\r
301 msg = Ext.isObject(error) ? error.status + ' ' + error.statusText : error;\r
302\r
303 Ext.MessageBox.show({\r
304 title: 'Delete Task Failed',\r
305 msg: msg,\r
306 icon: Ext.Msg.ERROR,\r
307 buttons: Ext.Msg.OK\r
308 });\r
309 }\r
310 });\r
311 }\r
312 }\r
313 });\r
314 },\r
315\r
316 /**\r
317 * Refreshes the task grid's list filter, and the task counts in the list tree\r
318 */\r
319 refreshListTree: function() {\r
320 // refresh the lists list view so that the task counts will be correct\r
321 this.getListTree().refreshView();\r
322 },\r
323\r
324 /**\r
325 * Handles a click on the "Edit" context menu item\r
326 * @param {Ext.menu.Item} item\r
327 * @param {EventObject} e\r
328 */\r
329 handleEditItemClick: function(item, e) {\r
330 this.showEditWindow(this.getContextMenu().getTask());\r
331 },\r
332\r
333 /**\r
334 * Handles a click on the "Edit Task" action column\r
335 * @param {Ext.grid.View} view\r
336 * @param {Number} rowIndex\r
337 * @param {Number} colIndex\r
338 * @param {Ext.grid.column.Action} column\r
339 * @param {EventObject} e\r
340 */\r
341 handleEditIconClick: function(view, rowIndex, colIndex, column, e) {\r
342 this.showEditWindow(view.getRecord(view.findTargetByEvent(e)));\r
343 },\r
344\r
345 /**\r
346 * Handles the task grid's "selectionchange" event.\r
347 * Disables or enables the task-related toolbar buttons depending on whether or not there is a selection.\r
348 * @param {Ext.selection.RowModel} selModel\r
349 * @param {SimpleTasks.model.Task[]} tasks\r
350 */\r
351 toggleButtons: function(selModel, tasks) {\r
352 var deleteTaskBtn = Ext.getCmp('delete-task-btn'),\r
353 markCompleteBtn = Ext.getCmp('mark-complete-btn'),\r
354 markActiveBtn = Ext.getCmp('mark-active-btn');\r
355\r
356 if(tasks.length === 0) {\r
357 deleteTaskBtn.disable();\r
358 markCompleteBtn.disable();\r
359 markActiveBtn.disable();\r
360 } else {\r
361 deleteTaskBtn.enable();\r
362 markCompleteBtn.enable();\r
363 markActiveBtn.enable();\r
364 }\r
365 },\r
366\r
367 /**\r
368 * Handles a click on the "New Task" button or context menu item\r
369 * focuses the title field on the new task form\r
370 * @param {Ext.Component} component\r
371 * @param {Ext.EventObject} e\r
372 */\r
373 focusTaskForm: function(component, e) {\r
374 this.getTaskForm().query('[name=title]')[0].focus();\r
375 },\r
376\r
377 /**\r
378 * Handles a click on the "Mark Complete" button or menu item\r
379 * Sets the selected task's "done" field to true\r
380 * @param {Ext.Component} component\r
381 * @param {Ext.EventObject} e\r
382 */\r
383 markComplete: function(component, e) {\r
384 var contextMenu = this.getContextMenu(),\r
385 task = contextMenu.isVisible() ? contextMenu.getTask() : this.getTaskGrid().getSelectionModel().getSelection()[0];\r
386\r
387 task.set('done', true);\r
388 task.set('reminder', null);\r
389 task.save({\r
390 failure: function(task, operation) {\r
391 var error = operation.getError(),\r
392 msg = Ext.isObject(error) ? error.status + ' ' + error.statusText : error;\r
393\r
394 Ext.MessageBox.show({\r
395 title: 'Mark Complete Failed',\r
396 msg: msg,\r
397 icon: Ext.Msg.ERROR,\r
398 buttons: Ext.Msg.OK\r
399 });\r
400 }\r
401 });\r
402 this.refreshListTree();\r
403 },\r
404\r
405 /**\r
406 * Handles a click on the "Mark Active" button\r
407 * Sets the selected task's "done" field to false\r
408 * @param {Ext.button.Button} button\r
409 * @param {Ext.EventObject} e\r
410 */\r
411 markActive: function(button, e) {\r
412 var contextMenu = this.getContextMenu(),\r
413 task = contextMenu.isVisible() ? contextMenu.getTask() : this.getTaskGrid().getSelectionModel().getSelection()[0];\r
414\r
415 task.set('done', false);\r
416 task.save({\r
417 failure: function(task, operation) {\r
418 var error = operation.getError(),\r
419 msg = Ext.isObject(error) ? error.status + ' ' + error.statusText : error;\r
420\r
421 Ext.MessageBox.show({\r
422 title: 'Mark Active Failed',\r
423 msg: msg,\r
424 icon: Ext.Msg.ERROR,\r
425 buttons: Ext.Msg.OK\r
426 });\r
427 }\r
428 });\r
429 this.refreshListTree();\r
430 },\r
431\r
432 /**\r
433 * Handles the task grid columnresize event.\r
434 * Synchronizes the width the column's associated form field with the width of the column\r
435 * @param {Ext.grid.header.Container} headerContainer\r
436 * @param {Ext.column.Column} column\r
437 * @param {Number} width The new column width\r
438 */\r
439 syncTaskFormFieldWidth: function(headerContainer, column, width) {\r
440 var field = this.getTaskForm().query('[name=' + column.dataIndex + ']')[0];\r
441 if (field) {\r
442 field.setWidth(width - 5);\r
443 }\r
444 },\r
445\r
446 /**\r
447 * Handles a click on the "Show All" button. Removes any filter on the done field so that all tasks will be displayed\r
448 * @param {Ext.button.Button} button\r
449 * @param {Ext.EventObject} e\r
450 */\r
451 filterAll: function(button, e) {\r
452 this.getTasksStore().clearFilter();\r
453 this.refreshListTree();\r
454 },\r
455\r
456 /**\r
457 * Handles a click on the "Show Active" button. Filters tasks by done = false\r
458 * @param {Ext.button.Button} button\r
459 * @param {Ext.EventObject} e\r
460 */\r
461 filterActive: function(button, e) {\r
462 this.getTasksStore().addFilter({\r
463 property: 'done',\r
464 value: false\r
465 });\r
466 this.refreshListTree();\r
467 },\r
468\r
469 /**\r
470 * Handles a click on the "Show Complete" button. Filters tasks by done = true.\r
471 * @param {Ext.button.Button} button\r
472 * @param {Ext.EventObject} e\r
473 */\r
474 filterComplete: function(button, e) {\r
475 this.getTasksStore().addFilter({\r
476 property: 'done',\r
477 value: true\r
478 });\r
479 this.refreshListTree();\r
480 },\r
481\r
482 /**\r
483 * Handles the tasks toolbar's render event\r
484 * Initializes the "Show All" Button to the pressed state\r
485 * @param {SimpleTasks.view.Toolbar} toolbar\r
486 */\r
487 initShowAll: function(toolbar) {\r
488 toolbar.getComponent('show-all-btn').toggle();\r
489 },\r
490\r
491 /**\r
492 * Handles a mouseenter event on a task grid item.\r
493 * Shows the item's action icons.\r
494 * @param {Ext.grid.View} view\r
495 * @param {SimpleTasks.model.Task} task\r
496 * @param {HTMLElement} node\r
497 * @param {Number} rowIndex\r
498 * @param {Ext.EventObject} e\r
499 */\r
500 showActions: function(view, task, node, rowIndex, e) {\r
501 var icons = Ext.fly(node).query('.x-action-col-icon');\r
502 Ext.each(icons, function(icon){\r
503 Ext.get(icon).removeCls('x-hidden');\r
504 });\r
505 },\r
506\r
507 /**\r
508 * Handles a mouseleave event on a task grid item.\r
509 * Hides the item's action icons.\r
510 * @param {Ext.grid.View} view\r
511 * @param {SimpleTasks.model.Task} task\r
512 * @param {HTMLElement} node\r
513 * @param {Number} rowIndex\r
514 * @param {Ext.EventObject} e\r
515 */\r
516 hideActions: function(view, task, node, rowIndex, e) {\r
517 var icons = Ext.fly(node).query('.x-action-col-icon');\r
518 Ext.each(icons, function(icon){\r
519 Ext.get(icon).addCls('x-hidden');\r
520 });\r
521 },\r
522\r
523 /**\r
524 * Handles the task grid's itemcontextmenu event\r
525 * Shows the task context menu.\r
526 * @param {Ext.grid.View} view\r
527 * @param {SimpleTasks.model.Task} task\r
528 * @param {HTMLElement} node\r
529 * @param {Number} rowIndex\r
530 * @param {Ext.EventObject} e\r
531 */\r
532 showContextMenu: function(view, task, node, rowIndex, e) {\r
533 var contextMenu = this.getContextMenu(),\r
534 markCompleteItem = Ext.getCmp('mark-complete-item'),\r
535 markActiveItem = Ext.getCmp('mark-active-item');\r
536\r
537 if(task.get('done')) {\r
538 markCompleteItem.hide();\r
539 markActiveItem.show();\r
540 } else {\r
541 markCompleteItem.show();\r
542 markActiveItem.hide();\r
543 }\r
544 contextMenu.setTask(task);\r
545 contextMenu.showAt(e.getX(), e.getY());\r
546 e.preventDefault();\r
547 },\r
548\r
549 /**\r
550 * Shows the "Edit Task" window\r
551 * @param {SimpleTasks.model.Task} task the task to edit\r
552 */\r
553 showEditWindow: function(task) {\r
554 var me = this,\r
555 taskEditWindow = me.getTaskEditWindow(),\r
556 form = taskEditWindow.down('form').getForm(),\r
557 reminderCheckbox = form.findField('has_reminder'),\r
558 dateField = form.findField('reminder_date'),\r
559 timeField = form.findField('reminder_time'),\r
560 reminder = task.get('reminder');\r
561\r
562 // Set the tasks title as the title of the edit window\r
563 taskEditWindow.setTitle('Edit Task - ' + task.get('title'));\r
564 // load the task data into the form\r
565 taskEditWindow.down('form').loadRecord(task);\r
566 // set the text of the toggle-complete button depending on the tasks "done" value\r
567 Ext.getCmp('toggle-complete-btn').setText(task.get('done') ? 'Mark Active' : 'Mark Complete');\r
568 taskEditWindow.show();\r
569\r
570 if(task.get('reminder')) {\r
571 // if the task already has a reminder set check the reminder checkbox and populate the reminder date and reminder time fields\r
572 reminderCheckbox.setValue(true);\r
573 dateField.setValue(Ext.Date.clearTime(reminder, true));\r
574 timeField.setValue(Ext.Date.format(reminder, timeField.format)); \r
575 } else {\r
576 // if the task does not have a reminder set uncheck the reminder checkbox and set the reminder date and time fields to null\r
577 reminderCheckbox.setValue(false);\r
578 dateField.setValue(null);\r
579 timeField.setValue(null); \r
580 }\r
581\r
582 if(task.get('done')) {\r
583 // if the task is done disable the reminder checkbox (reminders cannot be set on completed tasks)\r
584 reminderCheckbox.disable();\r
585 } else {\r
586 reminderCheckbox.enable();\r
587 }\r
588\r
589 },\r
590\r
591 /**\r
592 * Handles a click on the "Edit Task" window's cancel button\r
593 * Hides the "Edit Task" window\r
594 * @param {Ext.Button} button\r
595 * @param {Ext.EventObject} e\r
596 */\r
597 hideEditWindow: function(button, e) {\r
598 this.getTaskEditWindow().close();\r
599 },\r
600\r
601 /**\r
602 * Handles the change event on the task edit window's "has_reminder" checkbox\r
603 * Toggles the visibility of the reminder date and time fields\r
604 * @param {Ext.form.field.Checkbox} checkbox\r
605 * @param {Boolean} newValue\r
606 * @param {Boolean} oldValue\r
607 */\r
608 toggleReminderFields: function(checkbox, newValue, oldValue) {\r
609 var taskEditWindow = this.getTaskEditWindow(),\r
610 windowEl = taskEditWindow.getEl(),\r
611 form = taskEditWindow.down('form').getForm(),\r
612 task = form.getRecord(),\r
613 dateField = form.findField('reminder_date'),\r
614 timeField = form.findField('reminder_time'),\r
615 defaultTimeDate, defaultTimeMilliseconds;\r
616 \r
617 if(newValue) { // if the "has reminder" checkbox was checked\r
618 windowEl.mask('loading');\r
619 // get the default reminder time from the server or cache\r
620 this.getDefaultReminderTime(function(defaultTime) {\r
621 // enable the date and time fields\r
622 dateField.enable();\r
623 timeField.enable();\r
624 if(!dateField.getValue()) {\r
625 // if the reminder date has not already been set, default the reminder date to the task's due date\r
626 // or the current date if the task does not have a due date\r
627 dateField.setValue(task.get('due') || Ext.Date.clearTime(new Date()));\r
628 timeField.setValue(defaultTime);\r
629 }\r
630 // set the form's hidden reminder field by combining the reminder date and time fields\r
631 defaultTimeDate = timeField.getValue();\r
632 defaultTimeMilliseconds = defaultTimeDate - Ext.Date.clearTime(defaultTimeDate, true);\r
633 form.findField('reminder').setValue(new Date(dateField.getValue().getTime() + defaultTimeMilliseconds));\r
634 windowEl.unmask();\r
635 }, timeField.format);\r
636 } else { // if the "has reminder" checkbox was unchecked\r
637 // nullify the form's hidden reminder field and disable the reminder date and time fields\r
638 form.findField('reminder').setValue(null);\r
639 dateField.disable();\r
640 timeField.disable();\r
641 }\r
642 },\r
643\r
644 /**\r
645 * Handles a click on the "Task Edit" window's save button.\r
646 * @param {Ext.button.Button} button\r
647 * @param {Ext.EventObject} e\r
648 */\r
649 handleSaveTaskClick: function(button, e) {\r
650 this.saveEditWindow();\r
651 },\r
652\r
653 /**\r
654 * Updates the task record with the form data from the edit window and saves the task to the server.\r
655 */\r
656 saveEditWindow: function() {\r
657 var taskEditWindow = this.getTaskEditWindow(),\r
658 listTree = this.getListTree(),\r
659 windowEl = taskEditWindow.getEl(),\r
660 form = taskEditWindow.down('form').getForm(),\r
661 task = form.getRecord();\r
662\r
663 if (form.isValid()) {\r
664 windowEl.mask('saving');\r
665 form.updateRecord(task);\r
666 if (task.modified && task.modified.done === false) {\r
667 task.set('reminder', null);\r
668 }\r
669 task.save({\r
670 success: function(task, operation) {\r
671 windowEl.unmask();\r
672 taskEditWindow.close();\r
673 listTree.view.refresh();\r
674 },\r
675 failure: function(task, operation) {\r
676 var error = operation.getError(),\r
677 msg = Ext.isObject(error) ? error.status + ' ' + error.statusText : error;\r
678\r
679 Ext.MessageBox.show({\r
680 title: 'Edit Task Failed',\r
681 msg: msg,\r
682 icon: Ext.Msg.ERROR,\r
683 buttons: Ext.Msg.OK\r
684 });\r
685 windowEl.unmask();\r
686 }\r
687 });\r
688 } else {\r
689 Ext.Msg.alert('Invalid Data', 'Please correct form errors');\r
690 }\r
691 },\r
692\r
693 /**\r
694 * Syncronizes the value of the edit window's hidden reminder field whenever "reminder_date", or "reminder_time" is changed\r
695 * @param {Ext.form.field.Picker} field the date or time picker\r
696 * @param {Date} oldValue\r
697 * @param {Date} newValue\r
698 */\r
699 syncReminderField: function(field, oldValue, newValue) {\r
700 var form = this.getTaskEditWindow().down('form').getForm(),\r
701 reminderField = form.findField('reminder'),\r
702 date = form.findField('reminder_date').getValue(),\r
703 timeDate = form.findField('reminder_time').getValue(),\r
704 time, reminderDate;\r
705\r
706 if(date && timeDate) {\r
707 time = timeDate - Ext.Date.clearTime(timeDate, true);\r
708 reminderDate = new Date(date.getTime() + time);\r
709 reminderField.setValue(reminderDate); \r
710 }\r
711 },\r
712\r
713 /**\r
714 * Toggles the edit window's "done" field to true when the "Mark Complete" or "Mark Active" button on the edit window is clicked\r
715 * @param {Ext.button.Button} button\r
716 * @param {Ext.EventObject} e\r
717 */\r
718 toggleCompleteField: function(button, e) {\r
719 var taskEditWindow = this.getTaskEditWindow(),\r
720 doneField = taskEditWindow.down('form').getForm().findField('done');\r
721\r
722 if(doneField.getValue() === 'true') {\r
723 doneField.setValue(false);\r
724 } else {\r
725 doneField.setValue(true);\r
726 }\r
727 this.saveEditWindow();\r
728 },\r
729\r
730 /**\r
731 * Handles a click on the "Delete" button on the edit window.\r
732 * Deletes the task and closes the edit window\r
733 * @param {Ext.button.Button} button\r
734 * @param {Ext.EventObject} e\r
735 */\r
736 deleteTaskAndCloseEditWindow: function(button, e) {\r
737 var me = this,\r
738 taskEditWindow = me.getTaskEditWindow(),\r
739 task = taskEditWindow.down('form').getRecord();\r
740\r
741 me.deleteTask(task, function() {\r
742 me.getTaskEditWindow().close();\r
743 });\r
744 },\r
745\r
746 /**\r
747 * Handles the Task Grid's `reminderselect` event\r
748 * Sets a task's reminder\r
749 * @param {SimpleTasks.model.Task} task the underlying record of the row that was clicked to show the reminder menu\r
750 * @param {String|Number} value The value that was selected\r
751 */\r
752 setReminder: function(task, value) {\r
753 var me = this,\r
754 defaultTimeWindow = me.getDefaultTimeWindow(),\r
755 defaultTimeField = defaultTimeWindow.down('form').getForm().findField('default_time'),\r
756 defaultTimeDate, defaultTimeMilliseconds;\r
757\r
758 me.getDefaultReminderTime(function(defaultTime) {\r
759 if(value === 'set') {\r
760 // if the user selected "Set Default Time", show the default time window.\r
761 defaultTimeField.setValue(defaultTime);\r
762 defaultTimeWindow.show();\r
763 } else {\r
764 if(Ext.isNumber(value)) {\r
765 // if the user selected a reminder time, set the reminder by adding the user selected value to the due date\r
766 defaultTimeDate = Ext.Date.parse(defaultTime, defaultTimeField.format);\r
767 defaultTimeMilliseconds = defaultTimeDate - Ext.Date.clearTime(defaultTimeDate, true);\r
768 task.set('reminder', new Date(task.get('due').getTime() - (value * 86400000) + defaultTimeMilliseconds));\r
769 } else {\r
770 // if the user selected "No Reminder" set the reminder field to null\r
771 task.set('reminder', null);\r
772 }\r
773 task.save({\r
774 failure: function(task, operation) {\r
775 var error = operation.getError(),\r
776 msg = Ext.isObject(error) ? error.status + ' ' + error.statusText : error;\r
777\r
778 Ext.MessageBox.show({\r
779 title: 'Set Reminder Failed',\r
780 msg: msg,\r
781 icon: Ext.Msg.ERROR,\r
782 buttons: Ext.Msg.OK\r
783 });\r
784 }\r
785 });\r
786 }\r
787 }, defaultTimeField.format);\r
788 },\r
789\r
790 /**\r
791 * Gets the default reminder time and passes it to the callback function.\r
792 * Retrieves default reminder time from the server on the first call, then caches it for future calls.\r
793 * @param {Function} callback\r
794 * @param {String} timeFormat, the time format used to encode the time: the time format of the destination TimeField\r
795 */\r
796 getDefaultReminderTime: function(callback, timeFormat) {\r
797 var me = this,\r
798 defaultReminderTime;\r
799\r
800 if(me.defaultReminderTime) {\r
801 callback(me.defaultReminderTime);\r
802 } else {\r
803 me.defaultReminderTime = Ext.Date.format(Ext.Date.parse('8', 'g'), timeFormat || "g:i A"); // the default time if no value can be retrieved from storage\r
804 if (SimpleTasks.Settings.useLocalStorage) {\r
805 defaultReminderTime = localStorage.getItem('SimpleTasks-defaultReminderTime');\r
806 if (defaultReminderTime && Ext.Date.parse(defaultReminderTime, timeFormat)) {\r
807 me.defaultReminderTime = defaultReminderTime;\r
808 }\r
809 callback(me.defaultReminderTime);\r
810 } else {\r
811 Ext.Ajax.request({\r
812 url: 'php/config/read.php',\r
813 params: {\r
814 key: 'default.reminder.time'\r
815 },\r
816 success: function(response, options) {\r
817 var responseData = Ext.decode(response.responseText);\r
818 if(responseData.success && responseData.value && Ext.Date.parse(responseData.value, timeFormat)) {\r
819 me.defaultReminderTime = responseData.value;\r
820 }\r
821 callback(me.defaultReminderTime);\r
822 },\r
823 failure: function(response, options) {\r
824 callback(me.defaultReminderTime);\r
825 }\r
826 });\r
827 }\r
828 }\r
829 },\r
830\r
831 /**\r
832 * Hides the default reminder time window when the cancel button is clicked\r
833 * @param {Ext.button.Button} button\r
834 * @param {Ext.EventObject} e\r
835 */\r
836 hideDefaultTimeWindow: function(button, e) {\r
837 this.getDefaultTimeWindow().close();\r
838 },\r
839\r
840 /**\r
841 * Saves the default reminder time to the server when the OK button is clicked\r
842 * @param {Ext.button.Button} button\r
843 * @param {Ext.EventObject} e\r
844 */\r
845 saveDefaultTime: function(button, e) {\r
846 var me = this,\r
847 defaultTimeWindow = me.getDefaultTimeWindow(),\r
848 windowEl = defaultTimeWindow.getEl(),\r
849 field = defaultTimeWindow.down('form').getForm().findField('default_time'),\r
850 time = field.getRawValue();\r
851 \r
852 if (!field.isValid()) {\r
853 return;\r
854 }\r
855\r
856 if (SimpleTasks.Settings.useLocalStorage) {\r
857 localStorage.setItem('SimpleTasks-defaultReminderTime', time);\r
858 me.defaultReminderTime = time;\r
859 defaultTimeWindow.close();\r
860 } else {\r
861 windowEl.mask('saving');\r
862 Ext.Ajax.request({\r
863 url: 'php/config/update.php',\r
864 params: {\r
865 key: 'default.reminder.time',\r
866 value: time\r
867 },\r
868 success: function(response, options) {\r
869 var responseData = Ext.decode(response.responseText);\r
870\r
871 if(responseData.success) {\r
872 me.defaultReminderTime = time;\r
873 defaultTimeWindow.close();\r
874 } else {\r
875 Ext.MessageBox.show({\r
876 title: 'Set Default Time Failed',\r
877 msg: responseData.message,\r
878 icon: Ext.Msg.ERROR,\r
879 buttons: Ext.Msg.OK\r
880 });\r
881 }\r
882 windowEl.unmask();\r
883 },\r
884 failure: function(response, options) {\r
885 Ext.MessageBox.show({\r
886 title: 'Set Default Time Failed',\r
887 msg: response.status + ' ' + response.statusText,\r
888 icon: Ext.Msg.ERROR,\r
889 buttons: Ext.Msg.OK\r
890 });\r
891 windowEl.unmask();\r
892 }\r
893 });\r
894 }\r
895 },\r
896\r
897 /**\r
898 * Initializes checking for tasks that have passed their reminder date at 10 second intervals.\r
899 */\r
900 initReminderInterval: function() {\r
901 var me = this,\r
902 now, reminderDate;\r
903\r
904 setInterval(function() {\r
905 now = new Date();\r
906 me.getTasksStore().each(function(task) {\r
907 reminderDate = task.get('reminder');\r
908 if(reminderDate && reminderDate < now && !task.get('done')) {\r
909 me.showReminderWindow(task);\r
910 }\r
911 });\r
912 }, 10000);\r
913 },\r
914\r
915 /**\r
916 * Shows the reminder window for a given task\r
917 * @param {SimpleTasks.model.Task} task\r
918 */\r
919 showReminderWindow: function(task) {\r
920 var reminderWindow = this.getReminderWindow(),\r
921 reminderDetailsBox = reminderWindow.down('[cls=tasks-reminder-details]'),\r
922 title = task.get('title');\r
923\r
924 task.set('reminder', null);\r
925 task.save({\r
926 failure: function(task, operation) {\r
927 var error = operation.getError(),\r
928 msg = Ext.isObject(error) ? error.status + ' ' + error.statusText : error;\r
929\r
930 Ext.MessageBox.show({\r
931 title: 'Clear Reminder Failed',\r
932 msg: msg,\r
933 icon: Ext.Msg.ERROR,\r
934 buttons: Ext.Msg.OK\r
935 });\r
936 }\r
937 });\r
938 reminderWindow.setTask(task);\r
939 reminderWindow.setTitle('Reminder - ' + title);\r
940 reminderDetailsBox.update({\r
941 title: title,\r
942 due: task.get('due')\r
943 });\r
944 reminderWindow.show();\r
945 },\r
946\r
947\r
948 /**\r
949 * Handles a click on the snooze button on the reminder window.\r
950 * Sets the task's reminder date to the current date plus snooze time selected\r
951 * @param {Ext.button.Button} button\r
952 * @param {Ext.EventObject} e\r
953 */\r
954 snooze: function(button, e) {\r
955 var reminderWindow = button.findParentByType('window'),\r
956 task = reminderWindow.getTask(),\r
957 snoozeMilliseconds = reminderWindow.down('[name=snooze_time]').getValue() * 60000,\r
958 reminderDate = new Date(new Date().getTime() + snoozeMilliseconds);\r
959\r
960 task.set('reminder', reminderDate);\r
961 task.save({\r
962 failure: function(task, operation) {\r
963 var error = operation.getError(),\r
964 msg = Ext.isObject(error) ? error.status + ' ' + error.statusText : error;\r
965\r
966 Ext.MessageBox.show({\r
967 title: 'Set Reminder Failed',\r
968 msg: msg,\r
969 icon: Ext.Msg.ERROR,\r
970 buttons: Ext.Msg.OK\r
971 });\r
972 }\r
973 });\r
974 reminderWindow.close();\r
975 },\r
976\r
977 /**\r
978 * Handle's a click on the reminder window's dismiss button.\r
979 * Hides the reminder window.\r
980 * @param {Ext.button.Button} button\r
981 * @param {Ext.EventObject} e\r
982 */\r
983 dismissReminder: function(button, e) {\r
984 button.findParentByType('window').close();\r
985 }\r
986\r
987});\r