2
* Base smartmobile application logic for Nag.
4
* Copyright 2011-2013 Horde LLC (http://www.horde.org/)
6
* See the enclosed file COPYING for license information (GPL). If you
7
* did not receive this file, see http://www.horde.org/licenses/gpl.
9
* @author Michael J Rubinsky <mrubinsk@horde.org>
11
* @license http://www.horde.org/licenses/gpl GPL
20
currentList: undefined,
23
* Toggle the completion status of the task.
25
* @param object d The data object.
28
toggleComplete: function(d)
30
var parsed = d.options.parsedUrl;
35
task: parsed.params.task_id,
36
tasklist: parsed.params.tasklist
38
function(r) { NagMobile.toggleCompleteCallback(r, d.options.data) }
43
* Callback for the toggleComplete action
45
* @param object r The response object.
46
* @param object elt The element containing the task.
48
toggleCompleteCallback: function(r, elt)
56
NagMobile.tasks[elt.jqmData('tasklist')][elt.jqmData('task_id')].cp = true;
57
if (Nag.conf.showCompleted == 'incomplete' ||
58
Nag.conf.showCompleted == 'future-incomplete') {
60
elt.parent().remove();
62
elt.jqmData('icon', 'check')
64
.removeClass('ui-icon-nag-unchecked')
65
.addClass('ui-icon-check');
66
NagMobile.styleTask(elt, NagMobile.tasks[elt.jqmData('tasklist')][elt.jqmData('task_id')]);
71
NagMobile.tasks[elt.jqmData('tasklist')][elt.jqmData('task_id')].cp = false;
72
if (Nag.conf.showCompleted == 'complete') {
74
elt.parent().remove();
76
elt.jqmData('icon', 'minus')
78
.removeClass('ui-icon-check')
79
.addClass('ui-icon-nag-unchecked');
80
NagMobile.styleTask(elt, NagMobile.tasks[elt.jqmData('tasklist')][elt.jqmData('task_id')]);
86
* Get a task from the server.
88
* @param object d The data object.
92
var parsed = d.options.parsedUrl;
97
task: parsed.params.task_id,
98
tasklist: parsed.params.tasklist
100
NagMobile.getTaskCallback
102
$('#nag-taskform-view a[href^="#task-delete"]').show();
103
HordeMobile.changePage('nag-taskform-view', d);
107
* Callback for the getTask action.
109
* @param object r The response object.
111
getTaskCallback: function(r)
121
$("#task_title").val(task.n);
122
$("#task_desc").val(task.de);
123
$("#task_assignee").val(task.as);
124
$("task_private").prop("checked", task.pr).checkboxradio("refresh");
126
$("#task_due").val(Date.parse(task.dd).toString('yyyy-MM-dd'));
129
$("#task_start").val(Date.parse(task.s).toString('yyyy-MM-dd'));
131
var myselect = $("#task_priority");
132
myselect[0].selectedIndex = task.pr - 1;
133
myselect.selectmenu("refresh");
134
$("#task_completed").prop("checked", task.cp).checkboxradio("refresh");
135
$("#task_estimate").val(task.e);
136
$("#task_id").val(task.id);
137
$("#tasklist").val(task.l);
141
* Get a list of tasklists from the server and display the nag-lists view.
143
* @param object d The data object.
147
HordeMobile.changePage('nag-lists', d);
148
HordeMobile.doAction(
151
NagMobile.getTasklistsCallback
156
* Callback for the getTaskLists action
158
* @param object r The response object.
160
getTasklistsCallback: function(r)
166
var list = $('#nag-lists :jqmData(role="listview")'),
171
$.each(r.tasklists, function(i, l) {
172
count = count + l.count;
173
NagMobile.insertTasklist(list, l, false);
176
NagMobile.insertTasklist(
179
'name': Nag.strings.all,
184
list.listview('refresh');
188
* Insert a tasklist element into the tasklist list.
190
* @param object el The UL element.
191
* @param object l The list hash.
192
* @param boolean top Place new list at top of list if true.
194
insertTasklist: function(el, l, top)
196
var url = HordeMobile.createUrl('nag-list', { tasklist: l.id }),
199
NagMobile.tasklists[l.id] = l;
201
list = $('<li>').append($('<a>').attr({ href: url }).addClass('nag-tasklist')
202
.append($('<img>').attr({ 'src': Nag.conf.icons[(l.smart ? 'smartlist' : 'tasklist')] }).addClass('ui-li-icon'))
203
.append($('<h3>').text(l.name))
204
.append($('<span>').addClass('ui-li-count' + (l.overdue ? ' overdue' : '')).text(l.count))
215
* Retrieve a tasklist from the server and display the nag-list view.
217
* @param object d The data object.
221
var params = d.options.parsedUrl.params;
223
HordeMobile.doAction(
225
{ tasklist: params.tasklist },
226
NagMobile.listTasksCallback
228
$('#nag-list .smartmobile-title')
229
.text(NagMobile.tasklists[params.tasklist].name);
230
NagMobile.currentList = params.tasklist;
231
HordeMobile.changePage('nag-list', d);
235
* Callback for the listTasks action.
237
* @param object r The response object.
239
listTasksCallback: function(r)
245
NagMobile.tasks = {};
246
$.each(r.tasks, function(i, t) {
247
if (!NagMobile.tasks[t.l]) {
248
NagMobile.tasks[t.l] = {};
250
NagMobile.tasks[t.l][t.id] = t;
252
NagMobile.buildTaskList();
253
if (NagMobile.tasklists[NagMobile.currentList].smart == 1) {
254
$('#nag-list :jqmData(role="footer") a[href^="#nag-taskform-view"]').hide();
256
$('#nag-list :jqmData(role="footer") a[href^="#nag-taskform-view"]').show();
261
* Build the complete tasklist
263
buildTaskList: function()
265
var list = $('#nag-list :jqmData(role="listview")'),
268
$.each(NagMobile.tasks, function (i, l) {
269
$.each(l, function (i, t) {
271
NagMobile.insertTask(list, t);
275
$('#nag-notasks').hide();
277
$('#nag-notasks').show();
279
list.listview('refresh');
283
* Insert task into the view.
285
* @param object l The UL element.
286
* @param object t The task hash.
288
insertTask: function(l, t)
295
item = $('<li>').jqmData('icon', t.cp ? 'check' : 'nag-unchecked')
298
href: HordeMobile.createUrl('nag-taskform-view', params)
299
}).addClass('nag-task')
303
$('<p>').addClass('ui-li-aside')
306
$('<p>').text((t.de ? t.de : ''))
310
href: HordeMobile.createUrl('nag-toggle', params)
313
item.jqmData('task_id', t.id);
314
item.jqmData('tasklist', t.l);
315
NagMobile.styleTask(item, t);
320
* Handler for pageBeforeChange event
322
* @param object e The event object.
323
* @param object data The data object.
325
toPage: function(e, data)
327
switch (data.options.parsedUrl.view) {
329
NagMobile.toList(data);
333
case 'nag-taskform-view':
334
if (data.options.parsedUrl.params.task_id) {
335
NagMobile.getTask(data);
337
HordeMobile.changePage('nag-taskform-view', data);
338
$('#nag-taskform-view .smartmobile-title').text(Nag.strings.newTask);
344
NagMobile.toLists(data);
349
NagMobile.toggleComplete(data);
356
* Add the appropriate CSS classes to the task element based on the task's
357
* completion, due date etc...
359
* @param object l The tasks's LI element.
360
* @param object t The task hash.
362
styleTask: function(l, t)
364
var task_due = Date.parse(t.dd),
365
task_overdue = task_due ? (task_due.compareTo(new Date()) < 0 ? true : false) : false;
368
l.removeClass('closed');
370
l.removeClass('overdue');
372
l.addClass('overdue');
375
l.addClass('closed');
376
l.removeClass('overdue');
381
* Prepare the nag-taskform-view for entering a new task.
383
prepareFormForNew: function()
385
$('#nag-task-form')[0].reset();
387
// Must explicitly call refresh when the selectedIndex changes
388
// programmatically or the UI won't reflect the new value.
390
$("#task_priority").selectmenu("refresh");
392
$('#nag-task-form #tasklist').val('');
393
$('#nag-task-form #task_id').val('');
394
$('#nag-taskform-view a[href^="#task-delete"]').hide();
398
handleSubmit: function(e)
400
var form = $('#nag-task-form'),
401
data = HordeJquery.formToObject(form);
403
if (!data.hasOwnProperty('task_completed')) {
404
data.task_completed = 'off';
406
HordeMobile.doAction('saveTask', data, NagMobile.handleSubmitCallback);
409
handleSubmitCallback: function(r)
415
NagMobile.tasks[r.task.l][r.task.id] = r.task;
416
NagMobile.buildTaskList();
417
HordeMobile.changePage('nag-list');
420
handleCancel: function(e)
422
HordeMobile.changePage('nag-list');
425
handleDelete: function(e)
427
var taskid = $('#nag-taskform-view #task_id').val(),
428
tasklist = $('#nag-taskform-view #tasklist').val();
429
if (taskid && tasklist) {
430
HordeMobile.doAction('deleteTask', {
432
'tasklist': tasklist,
434
NagMobile.handleDeleteCallback
439
handleDeleteCallback: function(r)
446
delete NagMobile.tasks[r.l][r.deleted];
448
NagMobile.buildTaskList();
449
HordeMobile.changePage('nag-list');
452
onDocumentReady: function()
454
$(document).bind('pagebeforechange', NagMobile.toPage);
456
// Capture task completed clicks to add the current LI element to
457
// the page change data.
458
$('#nag-list :jqmData(role="listview")').on('click', 'li', function(e) {
459
var a = $(e.target).closest('a[href^="#nag-toggle"]');
461
$.mobile.changePage(a.attr('href'), { data: $(e.currentTarget) });
466
// Capture new task clicks.
467
$('#nag-list :jqmData(role="footer") a[href^="#nag-taskform-view"]').on('click', NagMobile.prepareFormForNew);
468
$('#nag-taskform-view a[href^="#task-submit"]').on('click', NagMobile.handleSubmit);
469
$('#nag-taskform-view a[href^="#task-cancel"]').on('click', NagMobile.handleCancel);
470
$('#nag-taskform-view a[href^="#task-delete"]').on('click', NagMobile.handleDelete);
472
NagMobile.tasklists = Nag.tasklists;
473
NagMobile.tasklists[undefined] = { 'name': Nag.strings.all };
478
$(NagMobile.onDocumentReady);