MDL-31830 course: improvements to JS coding style
[moodle.git] / course / yui / src / management / js / category.js
1 /**
2  * A managed category.
3  *
4  * @namespace M.course.management
5  * @class Category
6  * @constructor
7  * @extends Item
8  */
9 function Category() {
10     Category.superclass.constructor.apply(this, arguments);
11 }
12 Category.NAME = 'moodle-course-management-category';
13 Category.CSS_PREFIX = 'management-category';
14 Category.ATTRS = {
15     /**
16      * The category ID relating to this category.
17      * @attribute categoryid
18      * @type Number
19      * @writeOnce
20      * @default null
21      */
22     categoryid : {
23         getter : function (value, name) {
24             if (value === null) {
25                 value = this.get('node').getData('id');
26                 this.set(name, value);
27             }
28             return value;
29         },
30         value : null,
31         writeOnce : true
32     },
34     /**
35      * True if this category is the currently selected category.
36      * @attribute selected
37      * @type Boolean
38      * @default null
39      */
40     selected : {
41         getter : function(value, name) {
42             if (value === null) {
43                 value = this.get('node').getData(name);
44                 if (value === null) {
45                     value = false;
46                 }
47                 this.set(name, value);
48             }
49             return value;
50         },
51         value : null
52     },
54     /**
55      * An array of courses belonging to this category.
56      * @attribute courses
57      * @type Course[]
58      * @default Array
59      */
60     courses : {
61         validator : function(val) {
62             return Y.Lang.isArray(val);
63         },
64         value : []
65     }
66 };
67 Category.prototype = {
68     /**
69      * Initialises an instance of a Category.
70      * @method initializer
71      */
72     initializer : function() {
73         this.set('itemname', 'category');
74     },
76     /**
77      * Returns the name of the category.
78      * @method getName
79      * @returns {String}
80      */
81     getName : function() {
82         return this.get('node').one('a.categoryname').get('innerHTML');
83     },
85     /**
86      * Registers a course as belonging to this category.
87      * @method registerCourse
88      * @param {Course} course
89      */
90     registerCourse : function(course) {
91         var courses = this.get('courses');
92         courses.push(course);
93         this.set('courses', courses);
94     },
96     /**
97      * Handles a category related event.
98      *
99      * @method handle
100      * @param {String} action
101      * @param {EventFacade} e
102      * @returns {Boolean}
103      */
104     handle : function(action, e) {
105         var catarg = {categoryid : this.get('categoryid')};
106         switch (action) {
107             case 'moveup':
108                 e.preventDefault();
109                 this.get('console').performAjaxAction('movecategoryup', catarg, this.moveup, this);
110                 break;
111             case 'movedown':
112                 e.preventDefault();
113                 this.get('console').performAjaxAction('movecategorydown', catarg, this.movedown, this);
114                 break;
115             case 'show':
116                 e.preventDefault();
117                 this.get('console').performAjaxAction('showcategory', catarg, this.show, this);
118                 break;
119             case 'hide':
120                 e.preventDefault();
121                 this.get('console').performAjaxAction('hidecategory', catarg, this.hide, this);
122                 break;
123             case 'expand':
124                 e.preventDefault();
125                 if (this.get('node').getData('expanded') === '0') {
126                     this.get('node').setAttribute('data-expanded', '1').setData('expanded', 'true');
127                     this.get('console').performAjaxAction('getsubcategorieshtml', catarg, this.loadSubcategories, this);
128                 }
129                 this.expand();
130                 break;
131             case 'collapse':
132                 e.preventDefault();
133                 this.collapse();
134                 break;
135             default:
136                 Y.log('Invalid AJAX action requested of managed category.', 'warn', 'moodle-course-management');
137                 return false;
138         }
139     },
141     /**
142      * Expands the category making its sub categories visible.
143      * @method expand
144      */
145     expand : function() {
146         var node = this.get('node'),
147             action = node.one('a[data-action=expand]');
148         node.removeClass('collapsed');
149         action.setAttribute('data-action', 'collapse').one('img').setAttrs({
150             src : M.util.image_url('t/switch_minus', 'moodle'),
151             title : M.util.get_string('collapse', 'moodle'),
152             alt : M.util.get_string('collapse', 'moodle')
153         });
154     },
156     /**
157      * Collapses the category making its sub categories hidden.
158      * @method collapse
159      */
160     collapse : function() {
161         var node = this.get('node'),
162             action = node.one('a[data-action=collapse]');
163         node.addClass('collapsed');
164         action.setAttribute('data-action', 'expand').one('img').setAttrs({
165             src : M.util.image_url('t/switch_plus', 'moodle'),
166             title : M.util.get_string('expand', 'moodle'),
167             alt : M.util.get_string('expand', 'moodle')
168         });
169     },
171     /**
172      * Loads sub categories provided by an AJAX request..
173      *
174      * @method loadSubcategories
175      * @protected
176      * @param {Number} transactionid The transaction ID of the AJAX request (unique)
177      * @param {Object} response The response from the AJAX request.
178      * @param {Object} args The arguments given to the request.
179      * @return {Boolean} Returns true on success - false otherwise.
180      */
181     loadSubcategories : function(transactionid, response, args) {
182         var outcome = this.checkAjaxResponse(transactionid, response, args),
183             node = this.get('node'),
184             console = this.get('console');
185         if (outcome === false) {
186             Y.log('AJAX failed to load sub categories for '+this.get('itemname'), 'warn', 'moodle-course-management');
187             return false;
188         }
189         Y.log('AJAX loaded subcategories for '+this.get('itemname'), 'info', 'moodle-course-management');
190         node.append(outcome.html);
191         console.initialiseCategories(node);
192         if (M.core && M.core.actionmenu && M.core.actionmenu.newDOMNode) {
193             M.core.actionmenu.newDOMNode(node);
194         }
195         return true;
196     },
198     /**
199      * Moves the course to this category.
200      *
201      * @method moveCourseTo
202      * @param {Course} course
203      */
204     moveCourseTo : function(course) {
205         var self = this;
206         Y.use('moodle-core-notification-confirm', function() {
207             var confirm = new M.core.confirm({
208                 title : M.util.get_string('confirm', 'moodle'),
209                 question : M.util.get_string('confirmcoursemove', 'moodle', {
210                     course : course.getName(),
211                     category : self.getName()
212                 }),
213                 yesLabel : M.util.get_string('yes', 'moodle'),
214                 noLabel : M.util.get_string('no', 'moodle')
215             });
216             confirm.on('complete-yes', function() {
217                 confirm.hide();
218                 confirm.destroy();
219                 this.get('console').performAjaxAction('movecourseintocategory', {
220                     categoryid : this.get('categoryid'),
221                     courseid : course.get('courseid')
222                 }, this.completeMoveCourse, this);
223             }, self);
224             confirm.show();
225         });
226     },
228     /**
229      * Completes moving a course to this category.
230      * @method completeMoveCourse
231      * @protected
232      * @param {Number} transactionid The transaction ID of the AJAX request (unique)
233      * @param {Object} response The response from the AJAX request.
234      * @param {Object} args The arguments given to the request.
235      * @returns {Boolean}
236      */
237     completeMoveCourse : function(transactionid, response, args) {
238         var outcome = this.checkAjaxResponse(transactionid, response, args),
239             course;
240         if (outcome === false) {
241             Y.log('AJAX failed to move courses into this category: '+this.get('itemname'), 'warn', 'moodle-course-management');
242             return false;
243         }
244         course = this.get('console').getCourseById(args.courseid);
245         if (!course) {
246             Y.log('Course was moved but the course listing could not be found to reflect this', 'warn', 'moodle-course-management');
247             return false;
248         }
249         Y.log('Moved the course ('+course.getName()+') into this category ('+this.getName()+')', 'info', 'moodle-course-management');
250         this.highlight();
251         if (course) {
252             course.remove();
253         }
254         return true;
255     },
257     /**
258      * Makes an item visible.
259      *
260      * @method show
261      * @param {Number} transactionid The transaction ID of the AJAX request (unique)
262      * @param {Object} response The response from the AJAX request.
263      * @param {Object} args The arguments given to the request.
264      * @returns {Boolean}
265      */
266     show : function(transactionid, response, args) {
267         var outcome = this.checkAjaxResponse(transactionid, response, args);
268         if (outcome === false) {
269             Y.log('AJAX request to show '+this.get('itemname')+' by outcome.', 'warn', 'moodle-course-management');
270             return false;
271         }
273         this.markVisible();
274         if (outcome.categoryvisibility) {
275             this.updateChildVisibility(outcome.categoryvisibility);
276         }
277         if (outcome.coursevisibility) {
278             this.updateCourseVisiblity(outcome.coursevisibility);
279         }
280         this.updated();
281         Y.log('Success: category made visible by AJAX.', 'info', 'moodle-course-management');
282     },
284     /**
285      * Hides an item.
286      *
287      * @method hide
288      * @param {Number} transactionid The transaction ID of the AJAX request (unique)
289      * @param {Object} response The response from the AJAX request.
290      * @param {Object} args The arguments given to the request.
291      * @returns {Boolean}
292      */
293     hide : function(transactionid, response, args) {
294         var outcome = this.checkAjaxResponse(transactionid, response, args);
295         if (outcome === false) {
296             Y.log('AJAX request to hide '+this.get('itemname')+' by outcome.', 'warn', 'moodle-course-management');
297             return false;
298         }
299         this.markHidden();
300         if (outcome.categoryvisibility) {
301             this.updateChildVisibility(outcome.categoryvisibility);
302         }
303         if (outcome.coursevisibility) {
304             this.updateCourseVisiblity(outcome.coursevisibility);
305         }
306         this.updated();
307         Y.log('Success: '+this.get('itemname')+' made hidden by AJAX.', 'info', 'moodle-course-management');
308     },
310     /**
311      * Updates the visibility of child courses if required.
312      * @method updateCourseVisiblity
313      * @chainable
314      * @param courses
315      */
316     updateCourseVisiblity : function(courses) {
317         var console = this.get('console'),
318             key,
319             course;
320         try {
321             for (key in courses) {
322                 if (courses.hasOwnProperty[key]) {
323                     course = console.getCourseById(courses[key].id);
324                     if (course) {
325                         if (courses[key].show === "1") {
326                             course.markVisible();
327                         } else {
328                             course.markHidden();
329                         }
330                     }
331                 }
332             }
333         } catch (err) {
334             Y.log('Error trying to update course visibility: ' + err.message, 'warn', 'moodle-course-management');
335         }
336         return this;
337     },
339     /**
340      * Updates the visibility of subcategories if required.
341      * @method updateChildVisibility
342      * @chainable
343      * @param categories
344      */
345     updateChildVisibility : function(categories) {
346         var console = this.get('console'),
347             key,
348             category;
349         try {
350             for (key in categories) {
351                 if (categories.hasOwnProperty[key]) {
352                     category = console.getCategoryById(categories[key].id);
353                     if (category) {
354                         if (categories[key].show === "1") {
355                             category.markVisible();
356                         } else {
357                             category.markHidden();
358                         }
359                     }
360                 }
361             }
362         } catch (err) {
363             Y.log('Error trying to update category visibility: ' + err.message, 'warn', 'moodle-course-management');
364         }
365         return this;
366     }
367 };
368 Y.extend(Category, Item, Category.prototype);