Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
/**
2
 * Provides drop down menus for list of action links.
3
 *
4
 * @module moodle-course-management
5
 */
6
 
7
/**
8
 * Management JS console.
9
 *
10
 * Provides the organisation for course and category management JS.
11
 *
12
 * @namespace M.course.management
13
 * @class Console
14
 * @constructor
15
 * @extends Base
16
 */
17
Console = function() {
18
    Console.superclass.constructor.apply(this, arguments);
19
};
20
Console.NAME = 'moodle-course-management';
21
Console.CSS_PREFIX = 'management';
22
Console.ATTRS = {
23
    /**
24
     * The HTML element containing the management interface.
25
     * @attribute element
26
     * @type Node
27
     */
28
    element: {
29
        setter: function(node) {
30
            if (typeof node === 'string') {
31
                node = Y.one('#' + node);
32
            }
33
            return node;
34
        }
35
    },
36
 
37
    /**
38
     * The category listing container node.
39
     * @attribute categorylisting
40
     * @type Node
41
     * @default null
42
     */
43
    categorylisting: {
44
        value: null
45
    },
46
 
47
    /**
48
     * The course listing container node.
49
     * @attribute courselisting
50
     * @type Node
51
     * @default null
52
     */
53
    courselisting: {
54
        value: null
55
    },
56
 
57
    /**
58
     * The course details container node.
59
     * @attribute coursedetails
60
     * @type Node|null
61
     * @default null
62
     */
63
    coursedetails: {
64
        value: null
65
    },
66
 
67
    /**
68
     * The id of the currently active category.
69
     * @attribute activecategoryid
70
     * @type Number
71
     * @default null
72
     */
73
    activecategoryid: {
74
        value: null
75
    },
76
 
77
    /**
78
     * The id of the currently active course.
79
     * @attribute activecourseid
80
     * @type Number
81
     * @default Null
82
     */
83
    activecourseid: {
84
        value: null
85
    },
86
 
87
    /**
88
     * The categories that are currently available through the management interface.
89
     * @attribute categories
90
     * @type Array
91
     * @default []
92
     */
93
    categories: {
94
        setter: function(item, name) {
95
            if (Y.Lang.isArray(item)) {
96
                return item;
97
            }
98
            var items = this.get(name);
99
            items.push(item);
100
            return items;
101
        },
102
        value: []
103
    },
104
 
105
    /**
106
     * The courses that are currently available through the management interface.
107
     * @attribute courses
108
     * @type Course[]
109
     * @default Array
110
     */
111
    courses: {
112
        validator: function(val) {
113
            return Y.Lang.isArray(val);
114
        },
115
        value: []
116
    },
117
 
118
    /**
119
     * The currently displayed page of courses.
120
     * @attribute page
121
     * @type Number
122
     * @default null
123
     */
124
    page: {
125
        getter: function(value, name) {
126
            if (value === null) {
127
                value = this.get('element').getData(name);
128
                this.set(name, value);
129
            }
130
            return value;
131
        },
132
        value: null
133
    },
134
 
135
    /**
136
     * The total pages of courses that can be shown for this category.
137
     * @attribute totalpages
138
     * @type Number
139
     * @default null
140
     */
141
    totalpages: {
142
        getter: function(value, name) {
143
            if (value === null) {
144
                value = this.get('element').getData(name);
145
                this.set(name, value);
146
            }
147
            return value;
148
        },
149
        value: null
150
    },
151
 
152
    /**
153
     * The total number of courses belonging to this category.
154
     * @attribute totalcourses
155
     * @type Number
156
     * @default null
157
     */
158
    totalcourses: {
159
        getter: function(value, name) {
160
            if (value === null) {
161
                value = this.get('element').getData(name);
162
                this.set(name, value);
163
            }
164
            return value;
165
        },
166
        value: null
167
    },
168
 
169
    /**
170
     * The URL to use for AJAX actions/requests.
171
     * @attribute ajaxurl
172
     * @type String
173
     * @default /course/ajax/management.php
174
     */
175
    ajaxurl: {
176
        getter: function(value) {
177
            if (value === null) {
178
                value = M.cfg.wwwroot + '/course/ajax/management.php';
179
            }
180
            return value;
181
        },
182
        value: null
183
    },
184
 
185
    /**
186
     * The drag drop handler
187
     * @attribute dragdrop
188
     * @type DragDrop
189
     * @default null
190
     */
191
    dragdrop: {
192
        value: null
193
    }
194
};
195
Console.prototype = {
196
 
197
    /**
198
     * Gets set to true once the first categories have been initialised.
199
     * @property categoriesinit
200
     * @private
201
     * @type {boolean}
202
     */
203
    categoriesinit: false,
204
 
205
    /**
206
     * Initialises a new instance of the Console.
207
     * @method initializer
208
     */
209
    initializer: function() {
210
        Y.log('Initialising course category management console', 'info', 'moodle-course-management');
211
        this.set('element', 'coursecat-management');
212
        var element = this.get('element'),
213
            categorylisting = element.one('#category-listing'),
214
            courselisting = element.one('#course-listing'),
215
            selectedcategory = null,
216
            selectedcourse = null;
217
 
218
        if (categorylisting) {
219
            selectedcategory = categorylisting.one('.listitem[data-selected="1"]');
220
        }
221
        if (courselisting) {
222
            selectedcourse = courselisting.one('.listitem[data-selected="1"]');
223
        }
224
        this.set('categorylisting', categorylisting);
225
        this.set('courselisting', courselisting);
226
        this.set('coursedetails', element.one('#course-detail'));
227
        if (selectedcategory) {
228
            this.set('activecategoryid', selectedcategory.getData('id'));
229
        }
230
        if (selectedcourse) {
231
            this.set('activecourseid', selectedcourse.getData('id'));
232
        }
233
        this.initialiseCategories(categorylisting);
234
        this.initialiseCourses();
235
 
236
        if (courselisting) {
237
            // No need for dragdrop if we don't have a course listing.
238
            this.set('dragdrop', new DragDrop({console: this}));
239
        }
240
    },
241
 
242
    /**
243
     * Initialises all the categories being shown.
244
     * @method initialiseCategories
245
     * @private
246
     * @return {boolean}
247
     */
248
    initialiseCategories: function(listing) {
249
        var count = 0;
250
        if (!listing) {
251
            return false;
252
        }
253
 
254
        // Disable category bulk actions as nothing will be selected on initialise.
255
        var menumovecatto = listing.one('#menumovecategoriesto');
256
        if (menumovecatto) {
257
            menumovecatto.setAttribute('disabled', true);
258
        }
259
        var menuresortcategoriesby = listing.one('#menuresortcategoriesby');
260
        if (menuresortcategoriesby) {
261
            menuresortcategoriesby.setAttribute('disabled', true);
262
        }
263
        var menuresortcoursesby = listing.one('#menuresortcoursesby');
264
        if (menuresortcoursesby) {
265
            menuresortcoursesby.setAttribute('disabled', true);
266
        }
267
 
268
        listing.all('.listitem[data-id]').each(function(node) {
269
            this.set('categories', new Category({
270
                node: node,
271
                console: this
272
            }));
273
            count++;
274
        }, this);
275
        if (!this.categoriesinit) {
276
            this.get('categorylisting').delegate('click', this.handleCategoryDelegation, 'a[data-action]', this);
277
            this.get('categorylisting').delegate('click', this.handleCategoryDelegation, 'input[name="bcat[]"]', this);
278
            this.get('categorylisting').delegate('change', this.handleBulkSortByaction, '#menuselectsortby', this);
279
            this.categoriesinit = true;
280
            Y.log(count + ' categories being managed', 'info', 'moodle-course-management');
281
        } else {
282
            Y.log(count + ' new categories being managed', 'info', 'moodle-course-management');
283
        }
284
    },
285
 
286
    /**
287
     * Initialises all the categories being shown.
288
     * @method initialiseCourses
289
     * @private
290
     * @return {boolean}
291
     */
292
    initialiseCourses: function() {
293
        var category = this.getCategoryById(this.get('activecategoryid')),
294
            listing = this.get('courselisting'),
295
            count = 0;
296
        if (!listing) {
297
            return false;
298
        }
299
 
300
        // Disable course move to bulk action as nothing will be selected on initialise.
301
        var menumovecoursesto = listing.one('#menumovecoursesto');
302
        if (menumovecoursesto) {
303
            menumovecoursesto.setAttribute('disabled', true);
304
        }
305
 
306
        listing.all('.listitem[data-id]').each(function(node) {
307
            this.registerCourse(new Course({
308
                node: node,
309
                console: this,
310
                category: category
311
            }));
312
            count++;
313
        }, this);
314
        listing.delegate('click', this.handleCourseDelegation, 'a[data-action]', this);
315
        listing.delegate('click', this.handleCourseDelegation, 'input[name="bc[]"]', this);
316
        Y.log(count + ' courses being managed', 'info', 'moodle-course-management');
317
    },
318
 
319
    /**
320
     * Registers a course within the management display.
321
     * @method registerCourse
322
     * @param {Course} course
323
     */
324
    registerCourse: function(course) {
325
        var courses = this.get('courses');
326
        courses.push(course);
327
        this.set('courses', courses);
328
    },
329
 
330
    /**
331
     * Handles the event fired by a delegated course listener.
332
     *
333
     * @method handleCourseDelegation
334
     * @protected
335
     * @param {EventFacade} e
336
     */
337
    handleCourseDelegation: function(e) {
338
        var target = e.currentTarget,
339
            action = target.getData('action'),
340
            courseid = target.ancestor('.listitem').getData('id'),
341
            course = this.getCourseById(courseid);
342
        if (course) {
343
            course.handle(action, e);
344
        } else {
345
            Y.log('Course with ID ' + courseid + ' could not be found for delegation', 'error', 'moodle-course-management');
346
        }
347
    },
348
 
349
    /**
350
     * Handles the event fired by a delegated course listener.
351
     *
352
     * @method handleCategoryDelegation
353
     * @protected
354
     * @param {EventFacade} e
355
     */
356
    handleCategoryDelegation: function(e) {
357
        var target = e.currentTarget,
358
            action = target.getData('action'),
359
            categoryid = target.ancestor('.listitem').getData('id'),
360
            category = this.getCategoryById(categoryid);
361
        if (category) {
362
            category.handle(action, e);
363
        } else {
364
            Y.log('Could not find category to delegate to.', 'error', 'moodle-course-management');
365
        }
366
    },
367
 
368
    /**
369
     * Check if any course is selected.
370
     *
371
     * @method isCourseSelected
372
     * @param {Node} checkboxnode Checkbox node on which action happened.
373
     * @return bool
374
     */
375
    isCourseSelected: function(checkboxnode) {
376
        var selected = false;
377
 
378
        // If any course selected then show move to category select box.
379
        if (checkboxnode && checkboxnode.get('checked')) {
380
            selected = true;
381
        } else {
382
            var i,
383
                course,
384
                courses = this.get('courses'),
385
                length = courses.length;
386
            for (i = 0; i < length; i++) {
387
                if (courses.hasOwnProperty(i)) {
388
                    course = courses[i];
389
                    if (course.get('node').one('input[name="bc[]"]').get('checked')) {
390
                        selected = true;
391
                        break;
392
                    }
393
                }
394
            }
395
        }
396
        return selected;
397
    },
398
 
399
    /**
400
     * Check if any category is selected.
401
     *
402
     * @method isCategorySelected
403
     * @param {Node} checkboxnode Checkbox node on which action happened.
404
     * @return bool
405
     */
406
    isCategorySelected: function(checkboxnode) {
407
        var selected = false;
408
 
409
        // If any category selected then show move to category select box.
410
        if (checkboxnode && checkboxnode.get('checked')) {
411
            selected = true;
412
        } else {
413
            var i,
414
                category,
415
                categories = this.get('categories'),
416
                length = categories.length;
417
            for (i = 0; i < length; i++) {
418
                if (categories.hasOwnProperty(i)) {
419
                    category = categories[i];
420
                    if (category.get('node').one('input[name="bcat[]"]').get('checked')) {
421
                        selected = true;
422
                        break;
423
                    }
424
                }
425
            }
426
        }
427
        return selected;
428
    },
429
 
430
    /**
431
     * Handle bulk sort action.
432
     *
433
     * @method handleBulkSortByaction
434
     * @protected
435
     * @param {EventFacade} e
436
     */
437
    handleBulkSortByaction: function(e) {
438
        var sortcategoryby = this.get('categorylisting').one('#menuresortcategoriesby'),
439
            sortcourseby = this.get('categorylisting').one('#menuresortcoursesby'),
440
            sortbybutton = this.get('categorylisting').one('input[name="bulksort"]'),
441
            sortby = e;
442
 
443
        if (!sortby) {
444
            sortby = this.get('categorylisting').one('#menuselectsortby');
445
        } else {
446
            if (e && e.currentTarget) {
447
                sortby = e.currentTarget;
448
            }
449
        }
450
 
451
        // If no sortby select found then return as we can't do anything.
452
        if (!sortby) {
453
            return;
454
        }
455
 
456
        if ((this.get('categories').length <= 1) || (!this.isCategorySelected() &&
457
                (sortby.get("options").item(sortby.get('selectedIndex')).getAttribute('value') === 'selectedcategories'))) {
458
            if (sortcategoryby) {
459
                sortcategoryby.setAttribute('disabled', true);
460
            }
461
            if (sortcourseby) {
462
                sortcourseby.setAttribute('disabled', true);
463
            }
464
            if (sortbybutton) {
465
                sortbybutton.setAttribute('disabled', true);
466
            }
467
        } else {
468
            if (sortcategoryby) {
469
                sortcategoryby.removeAttribute('disabled');
470
            }
471
            if (sortcourseby) {
472
                sortcourseby.removeAttribute('disabled');
473
            }
474
            if (sortbybutton) {
475
                sortbybutton.removeAttribute('disabled');
476
            }
477
        }
478
    },
479
 
480
    /**
481
     * Returns the category with the given ID.
482
     * @method getCategoryById
483
     * @param {Number} id
484
     * @return {Category|Boolean} The category or false if it can't be found.
485
     */
486
    getCategoryById: function(id) {
487
        var i,
488
            category,
489
            categories = this.get('categories'),
490
            length = categories.length;
491
        for (i = 0; i < length; i++) {
492
            if (categories.hasOwnProperty(i)) {
493
                category = categories[i];
494
                if (category.get('categoryid') === id) {
495
                    return category;
496
                }
497
            }
498
        }
499
        return false;
500
    },
501
 
502
    /**
503
     * Returns the course with the given id.
504
     * @method getCourseById
505
     * @param {Number} id
506
     * @return {Course|Boolean} The course or false if not found/
507
     */
508
    getCourseById: function(id) {
509
        var i,
510
            course,
511
            courses = this.get('courses'),
512
            length = courses.length;
513
        for (i = 0; i < length; i++) {
514
            if (courses.hasOwnProperty(i)) {
515
                course = courses[i];
516
                if (course.get('courseid') === id) {
517
                    return course;
518
                }
519
            }
520
        }
521
        return false;
522
    },
523
 
524
    /**
525
     * Removes the course with the given ID.
526
     * @method removeCourseById
527
     * @param {Number} id
528
     */
529
    removeCourseById: function(id) {
530
        var courses = this.get('courses'),
531
            length = courses.length,
532
            course,
533
            i;
534
        for (i = 0; i < length; i++) {
535
            course = courses[i];
536
            if (course.get('courseid') === id) {
537
                courses.splice(i, 1);
538
                break;
539
            }
540
        }
541
    },
542
 
543
    /**
544
     * Performs an AJAX action.
545
     *
546
     * @method performAjaxAction
547
     * @param {String} action The action to perform.
548
     * @param {Object} args The arguments to pass through with teh request.
549
     * @param {Function} callback The function to call when all is done.
550
     * @param {Object} context The object to use as the context for the callback.
551
     */
552
    performAjaxAction: function(action, args, callback, context) {
553
        var io = new Y.IO();
554
        args.action = action;
555
        args.ajax = '1';
556
        args.sesskey = M.cfg.sesskey;
557
        if (callback === null) {
558
            callback = function() {
559
                Y.log("'Action '" + action + "' completed", 'debug', 'moodle-course-management');
560
            };
561
        }
562
        io.send(this.get('ajaxurl'), {
563
            method: 'POST',
564
            on: {
565
                complete: callback
566
            },
567
            context: context,
568
            data: args,
569
            'arguments': args
570
        });
571
    }
572
};
573
Y.extend(Console, Y.Base, Console.prototype);
574
 
575
M.course = M.course || {};
576
M.course.management = M.course.management || {};
577
M.course.management.console = null;
578
 
579
/**
580
 * Initalises the course management console.
581
 *
582
 * @method M.course.management.init
583
 * @static
584
 * @param {Object} config
585
 */
586
M.course.management.init = function(config) {
587
    M.course.management.console = new Console(config);
588
};