~ubuntu-branches/ubuntu/vivid/php-horde-nag/vivid

« back to all changes in this revision

Viewing changes to nag-4.1.3/js/smartmobile.js

  • Committer: Package Import Robot
  • Author(s): Mathieu Parent
  • Date: 2013-10-29 22:01:43 UTC
  • mfrom: (1.1.5)
  • Revision ID: package-import@ubuntu.com-20131029220143-k16crjhccwr56jxq
Tags: 4.1.3-1
New upstream version 4.1.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
 * Base smartmobile application logic for Nag.
 
3
 *
 
4
 * Copyright 2011-2013 Horde LLC (http://www.horde.org/)
 
5
 *
 
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.
 
8
 *
 
9
 * @author   Michael J Rubinsky <mrubinsk@horde.org>
 
10
 * @category Horde
 
11
 * @license  http://www.horde.org/licenses/gpl GPL
 
12
 * @package  Nag
 
13
 */
 
14
var NagMobile = {
 
15
 
 
16
    tasklists: {},
 
17
 
 
18
    tasks: {},
 
19
 
 
20
    currentList: undefined,
 
21
 
 
22
    /**
 
23
     * Toggle the completion status of the task.
 
24
     *
 
25
     * @param object d  The data object.
 
26
     */
 
27
 
 
28
    toggleComplete: function(d)
 
29
    {
 
30
        var parsed = d.options.parsedUrl;
 
31
 
 
32
        HordeMobile.doAction(
 
33
            'smartmobileToggle',
 
34
            {
 
35
                task: parsed.params.task_id,
 
36
                tasklist: parsed.params.tasklist
 
37
            },
 
38
            function(r) { NagMobile.toggleCompleteCallback(r, d.options.data) }
 
39
        );
 
40
    },
 
41
 
 
42
    /**
 
43
     * Callback for the toggleComplete action
 
44
     *
 
45
     * @param object r    The response object.
 
46
     * @param object elt  The element containing the task.
 
47
     */
 
48
    toggleCompleteCallback: function(r, elt)
 
49
    {
 
50
        if (!r.data) {
 
51
            return;
 
52
        }
 
53
 
 
54
        switch (r.data) {
 
55
        case 'complete':
 
56
            NagMobile.tasks[elt.jqmData('tasklist')][elt.jqmData('task_id')].cp = true;
 
57
            if (Nag.conf.showCompleted == 'incomplete' ||
 
58
                Nag.conf.showCompleted == 'future-incomplete') {
 
59
                // Hide the task
 
60
                elt.parent().remove();
 
61
            } else {
 
62
                elt.jqmData('icon', 'check')
 
63
                    .find('span.ui-icon')
 
64
                    .removeClass('ui-icon-nag-unchecked')
 
65
                    .addClass('ui-icon-check');
 
66
                NagMobile.styleTask(elt, NagMobile.tasks[elt.jqmData('tasklist')][elt.jqmData('task_id')]);
 
67
            }
 
68
            break;
 
69
 
 
70
        default:
 
71
            NagMobile.tasks[elt.jqmData('tasklist')][elt.jqmData('task_id')].cp = false;
 
72
            if (Nag.conf.showCompleted == 'complete') {
 
73
                // Hide the task
 
74
                elt.parent().remove();
 
75
            } else {
 
76
                elt.jqmData('icon', 'minus')
 
77
                    .find('span.ui-icon')
 
78
                    .removeClass('ui-icon-check')
 
79
                    .addClass('ui-icon-nag-unchecked');
 
80
                NagMobile.styleTask(elt, NagMobile.tasks[elt.jqmData('tasklist')][elt.jqmData('task_id')]);
 
81
            }
 
82
        }
 
83
    },
 
84
 
 
85
    /**
 
86
     * Get a task from the server.
 
87
     *
 
88
     * @param object d  The data object.
 
89
     */
 
90
    getTask: function(d)
 
91
    {
 
92
        var parsed = d.options.parsedUrl;
 
93
 
 
94
        HordeMobile.doAction(
 
95
            'getTask',
 
96
            {
 
97
                task: parsed.params.task_id,
 
98
                tasklist: parsed.params.tasklist
 
99
            },
 
100
            NagMobile.getTaskCallback
 
101
        );
 
102
        $('#nag-taskform-view a[href^="#task-delete"]').show();
 
103
        HordeMobile.changePage('nag-taskform-view', d);
 
104
    },
 
105
 
 
106
    /**
 
107
     * Callback for the getTask action.
 
108
     *
 
109
     * @param object r  The response object.
 
110
     */
 
111
    getTaskCallback: function(r)
 
112
    {
 
113
        if (!r.task) {
 
114
            return;
 
115
        }
 
116
 
 
117
        var task = r.task,
 
118
            f = $('form')[0];
 
119
 
 
120
        f.reset();
 
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");
 
125
        if (task.dd) {
 
126
            $("#task_due").val(Date.parse(task.dd).toString('yyyy-MM-dd'));
 
127
        }
 
128
        if (task.s) {
 
129
            $("#task_start").val(Date.parse(task.s).toString('yyyy-MM-dd'));
 
130
        }
 
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);
 
138
    },
 
139
 
 
140
    /**
 
141
     * Get a list of tasklists from the server and display the nag-lists view.
 
142
     *
 
143
     * @param object d  The data object.
 
144
     */
 
145
    toLists: function(d)
 
146
    {
 
147
        HordeMobile.changePage('nag-lists', d);
 
148
        HordeMobile.doAction(
 
149
            'getTaskLists',
 
150
            {},
 
151
            NagMobile.getTasklistsCallback
 
152
        );
 
153
    },
 
154
 
 
155
    /**
 
156
     * Callback for the getTaskLists action
 
157
     *
 
158
     * @param object r  The response object.
 
159
     */
 
160
    getTasklistsCallback: function(r)
 
161
    {
 
162
        if (!r.tasklists) {
 
163
            return;
 
164
        }
 
165
 
 
166
        var list = $('#nag-lists :jqmData(role="listview")'),
 
167
            count = 0;
 
168
 
 
169
        list.empty();
 
170
 
 
171
        $.each(r.tasklists, function(i, l) {
 
172
            count = count + l.count;
 
173
            NagMobile.insertTasklist(list, l, false);
 
174
        });
 
175
 
 
176
        NagMobile.insertTasklist(
 
177
            list,
 
178
            {
 
179
                'name': Nag.strings.all,
 
180
                'count': count
 
181
            },
 
182
            true
 
183
        );
 
184
        list.listview('refresh');
 
185
    },
 
186
 
 
187
     /**
 
188
      * Insert a tasklist element into the tasklist list.
 
189
      *
 
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.
 
193
      */
 
194
    insertTasklist: function(el, l, top)
 
195
    {
 
196
        var url = HordeMobile.createUrl('nag-list', { tasklist: l.id }),
 
197
            list;
 
198
 
 
199
        NagMobile.tasklists[l.id] = l;
 
200
 
 
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))
 
205
        );
 
206
 
 
207
        if (top) {
 
208
            el.prepend(list);
 
209
        } else {
 
210
            el.append(list);
 
211
        }
 
212
    },
 
213
 
 
214
    /**
 
215
     * Retrieve a tasklist from the server and display the nag-list view.
 
216
     *
 
217
     * @param object d  The data object.
 
218
     */
 
219
    toList: function(d)
 
220
    {
 
221
        var params = d.options.parsedUrl.params;
 
222
 
 
223
        HordeMobile.doAction(
 
224
            'listTasks',
 
225
            { tasklist: params.tasklist },
 
226
            NagMobile.listTasksCallback
 
227
        );
 
228
        $('#nag-list .smartmobile-title')
 
229
            .text(NagMobile.tasklists[params.tasklist].name);
 
230
        NagMobile.currentList = params.tasklist;
 
231
        HordeMobile.changePage('nag-list', d);
 
232
    },
 
233
 
 
234
    /**
 
235
     * Callback for the listTasks action.
 
236
     *
 
237
     * @param object r  The response object.
 
238
     */
 
239
    listTasksCallback: function(r)
 
240
    {
 
241
        if (!r.tasks) {
 
242
            return;
 
243
        }
 
244
 
 
245
        NagMobile.tasks = {};
 
246
        $.each(r.tasks, function(i, t) {
 
247
            if (!NagMobile.tasks[t.l]) {
 
248
                NagMobile.tasks[t.l] = {};
 
249
            }
 
250
            NagMobile.tasks[t.l][t.id] = t;
 
251
        });
 
252
        NagMobile.buildTaskList();
 
253
        if (NagMobile.tasklists[NagMobile.currentList].smart == 1) {
 
254
            $('#nag-list :jqmData(role="footer") a[href^="#nag-taskform-view"]').hide();
 
255
        } else {
 
256
            $('#nag-list :jqmData(role="footer") a[href^="#nag-taskform-view"]').show();
 
257
        }
 
258
    },
 
259
 
 
260
    /**
 
261
     * Build the complete tasklist
 
262
     */
 
263
    buildTaskList: function()
 
264
    {
 
265
        var list = $('#nag-list :jqmData(role="listview")'),
 
266
            count = 0;
 
267
        list.empty();
 
268
        $.each(NagMobile.tasks, function (i, l) {
 
269
            $.each(l, function (i, t) {
 
270
                count++;
 
271
                NagMobile.insertTask(list, t);
 
272
            });
 
273
        });
 
274
        if (count > 0) {
 
275
            $('#nag-notasks').hide();
 
276
        } else {
 
277
            $('#nag-notasks').show();
 
278
        }
 
279
        list.listview('refresh');
 
280
    },
 
281
 
 
282
    /**
 
283
     * Insert task into the view.
 
284
     *
 
285
     * @param object l  The UL element.
 
286
     * @param object t  The task hash.
 
287
     */
 
288
    insertTask: function(l, t)
 
289
    {
 
290
        var params = {
 
291
            task_id: t.id,
 
292
            tasklist: t.l
 
293
        }, item;
 
294
 
 
295
        item = $('<li>').jqmData('icon', t.cp ? 'check' : 'nag-unchecked')
 
296
            .append(
 
297
                $('<a>').attr({
 
298
                    href: HordeMobile.createUrl('nag-taskform-view', params)
 
299
                }).addClass('nag-task')
 
300
                .append(
 
301
                    $('<h3>').text(t.n)
 
302
                ).append(
 
303
                    $('<p>').addClass('ui-li-aside')
 
304
                        .text(t.dd)
 
305
                ).append(
 
306
                    $('<p>').text((t.de ? t.de : ''))
 
307
                )
 
308
            ).append(
 
309
                $('<a>').attr({
 
310
                    href: HordeMobile.createUrl('nag-toggle', params)
 
311
                })
 
312
            );
 
313
        item.jqmData('task_id', t.id);
 
314
        item.jqmData('tasklist', t.l);
 
315
        NagMobile.styleTask(item, t);
 
316
        l.append(item);
 
317
    },
 
318
 
 
319
    /**
 
320
     * Handler for pageBeforeChange event
 
321
     *
 
322
     * @param object e     The event object.
 
323
     * @param object data  The data object.
 
324
     */
 
325
    toPage: function(e, data)
 
326
    {
 
327
        switch (data.options.parsedUrl.view) {
 
328
        case 'nag-list':
 
329
            NagMobile.toList(data);
 
330
            e.preventDefault();
 
331
            break;
 
332
 
 
333
        case 'nag-taskform-view':
 
334
            if (data.options.parsedUrl.params.task_id) {
 
335
                NagMobile.getTask(data);
 
336
            } else {
 
337
                HordeMobile.changePage('nag-taskform-view', data);
 
338
                $('#nag-taskform-view .smartmobile-title').text(Nag.strings.newTask);
 
339
            }
 
340
            e.preventDefault();
 
341
            break;
 
342
 
 
343
        case 'nag-lists':
 
344
            NagMobile.toLists(data);
 
345
            e.preventDefault();
 
346
            break;
 
347
 
 
348
        case 'nag-toggle':
 
349
            NagMobile.toggleComplete(data);
 
350
            e.preventDefault();
 
351
            break;
 
352
        }
 
353
    },
 
354
 
 
355
    /**
 
356
     * Add the appropriate CSS classes to the task element based on the task's
 
357
     * completion, due date etc...
 
358
     *
 
359
     * @param object l  The tasks's LI element.
 
360
     * @param object t  The task hash.
 
361
     */
 
362
    styleTask: function(l, t)
 
363
    {
 
364
        var task_due = Date.parse(t.dd),
 
365
            task_overdue = task_due ? (task_due.compareTo(new Date()) < 0 ? true : false) : false;
 
366
 
 
367
        if (!t.cp) {
 
368
            l.removeClass('closed');
 
369
            if (!task_overdue) {
 
370
                l.removeClass('overdue');
 
371
            } else {
 
372
                l.addClass('overdue');
 
373
            }
 
374
        } else {
 
375
            l.addClass('closed');
 
376
            l.removeClass('overdue');
 
377
        }
 
378
    },
 
379
 
 
380
    /**
 
381
     * Prepare the nag-taskform-view for entering a new task.
 
382
     */
 
383
    prepareFormForNew: function()
 
384
    {
 
385
        $('#nag-task-form')[0].reset();
 
386
 
 
387
        // Must explicitly call refresh when the selectedIndex changes
 
388
        // programmatically or the UI won't reflect the new value.
 
389
        try {
 
390
            $("#task_priority").selectmenu("refresh");
 
391
        } catch(e) {}
 
392
        $('#nag-task-form #tasklist').val('');
 
393
        $('#nag-task-form #task_id').val('');
 
394
        $('#nag-taskform-view a[href^="#task-delete"]').hide();
 
395
    },
 
396
 
 
397
 
 
398
    handleSubmit: function(e)
 
399
    {
 
400
        var form = $('#nag-task-form'),
 
401
            data = HordeJquery.formToObject(form);
 
402
 
 
403
        if (!data.hasOwnProperty('task_completed')) {
 
404
            data.task_completed = 'off';
 
405
        }
 
406
        HordeMobile.doAction('saveTask', data, NagMobile.handleSubmitCallback);
 
407
    },
 
408
 
 
409
    handleSubmitCallback: function(r)
 
410
    {
 
411
        if (!r.task) {
 
412
            return;
 
413
        }
 
414
 
 
415
        NagMobile.tasks[r.task.l][r.task.id] = r.task;
 
416
        NagMobile.buildTaskList();
 
417
        HordeMobile.changePage('nag-list');
 
418
    },
 
419
 
 
420
    handleCancel: function(e)
 
421
    {
 
422
        HordeMobile.changePage('nag-list');
 
423
    },
 
424
 
 
425
    handleDelete: function(e)
 
426
    {
 
427
        var taskid = $('#nag-taskform-view #task_id').val(),
 
428
            tasklist = $('#nag-taskform-view #tasklist').val();
 
429
        if (taskid && tasklist) {
 
430
            HordeMobile.doAction('deleteTask', {
 
431
                    'task_id': taskid,
 
432
                    'tasklist': tasklist,
 
433
                },
 
434
                NagMobile.handleDeleteCallback
 
435
            );
 
436
        }
 
437
    },
 
438
 
 
439
    handleDeleteCallback: function(r)
 
440
    {
 
441
        if (!r.l) {
 
442
            return;
 
443
        }
 
444
 
 
445
        if (r.deleted) {
 
446
            delete NagMobile.tasks[r.l][r.deleted];
 
447
        }
 
448
        NagMobile.buildTaskList();
 
449
        HordeMobile.changePage('nag-list');
 
450
    },
 
451
 
 
452
    onDocumentReady: function()
 
453
    {
 
454
        $(document).bind('pagebeforechange', NagMobile.toPage);
 
455
 
 
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"]');
 
460
            if (a.length) {
 
461
                $.mobile.changePage(a.attr('href'), { data: $(e.currentTarget) });
 
462
                return false;
 
463
            }
 
464
        });
 
465
 
 
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);
 
471
 
 
472
        NagMobile.tasklists = Nag.tasklists;
 
473
        NagMobile.tasklists[undefined] = { 'name': Nag.strings.all };
 
474
    }
 
475
 
 
476
};
 
477
 
 
478
$(NagMobile.onDocumentReady);