6c22963ef33f7f51aa12a8e999e5fca5aca488f7
[moodle.git] / enrol / cohort / yui / quickenrolment / quickenrolment.js
1 YUI.add('moodle-enrol_cohort-quickenrolment', function(Y) {
3     var CONTROLLERNAME = 'Quick cohort enrolment controller',
4         COHORTNAME = 'Cohort',
5         COHORTID = 'cohortid',
6         ENROLLED = 'enrolled',
7         NAME = 'name',
8         USERS = 'users',
9         COURSEID = 'courseid',
10         ASSIGNABLEROLES = 'assignableRoles',
11         DEFAULTCOHORTROLE = 'defaultCohortRole',
12         COHORTS = 'cohorts',
13         MORERESULTS = 'moreresults',
14         FIRSTPAGE = 'firstpage',
15         OFFSET = 'offset',
16         PANELID = 'qce-panel-',
17         REQUIREREFRESH = 'requiresRefresh',
18         SEARCH = 'search',
19         URL = 'url',
20         AJAXURL = 'ajaxurl',
21         MANUALENROLMENT = 'manualEnrolment',
22         CSS = {
23             COHORT : 'qce-cohort',
24             COHORTS : 'qce-cohorts',
25             COHORTBUTTON : 'qce-cohort-button',
26             COHORTENROLLED : 'qce-cohort-enrolled',
27             COHORTNAME : 'qce-cohort-name',
28             COHORTUSERS : 'qce-cohort-users',
29             ENROLUSERS : 'canenrolusers',
30             FOOTER : 'qce-footer',
31             HIDDEN : 'hidden',
32             LIGHTBOX : 'qce-loading-lightbox',
33             LOADINGICON : 'loading-icon',
34             MORERESULTS : 'qce-more-results',
35             PANEL : 'qce-panel',
36             PANELCONTENT : 'qce-panel-content',
37             PANELCOHORTS : 'qce-enrollable-cohorts',
38             PANELROLES : 'qce-assignable-roles',
39             PANELCONTROLS : 'qce-panel-controls',
40             SEARCH : 'qce-search'
41         },
42         COUNT = 0;
45     var CONTROLLER = function(config) {
46         CONTROLLER.superclass.constructor.apply(this, arguments);
47     };
48     CONTROLLER.prototype = {
49         initializer : function(config) {
50             COUNT ++;
51             this.publish('assignablerolesloaded', {fireOnce:true});
52             this.publish('cohortsloaded');
53             this.publish('defaultcohortroleloaded', {fireOnce:true});
55             var base = Y.Node.create('<div class="'+CSS.PANELCONTENT+'"></div>')
56                 .append(Y.Node.create('<div class="'+CSS.PANELROLES+'"></div>'))
57                 .append(Y.Node.create('<div class="'+CSS.PANELCOHORTS+'"></div>'))
58                 .append(Y.Node.create('<div class="'+CSS.FOOTER+'"></div>')
59                     .append(Y.Node.create('<div class="'+CSS.SEARCH+'"><label>'+M.str.enrol_cohort.cohortsearch+':</label></div>')
60                         .append(Y.Node.create('<input type="text" id="enrolcohortsearch" value="" />'))
61                     )
62                 )
63                 .append(Y.Node.create('<div class="'+CSS.LIGHTBOX+' '+CSS.HIDDEN+'"></div>')
64                     .append(Y.Node.create('<img alt="loading" class="'+CSS.LOADINGICON+'" />')
65                         .setAttribute('src', M.util.image_url('i/loading', 'moodle')))
66                     .setStyle('opacity', 0.5)
67                 );
69             var close = Y.Node.create('<div class="close"></div>');
70             var panel = new Y.Overlay({
71                 headerContent : Y.Node.create('<div></div>').append(Y.Node.create('<h2>'+M.str.enrol.enrolcohort+'</h2>')).append(close),
72                 bodyContent : base,
73                 constrain : true,
74                 centered : true,
75                 id : PANELID+COUNT,
76                 visible : false
77             });
79             // display the wheel on ajax events
80             Y.on('io:start', function() {
81                 base.one('.'+CSS.LIGHTBOX).removeClass(CSS.HIDDEN);
82             }, this);
83             Y.on('io:end', function() {
84                 base.one('.'+CSS.LIGHTBOX).addClass(CSS.HIDDEN);
85             }, this);
87             this.set(SEARCH, base.one('#enrolcohortsearch'));
88             Y.on('key', this.getCohorts, this.get(SEARCH), 'down:13', this, false);
90             panel.get('boundingBox').addClass(CSS.PANEL);
91             panel.render(Y.one(document.body));
92             this.on('show', function(){
93                 this.set('centered', true);
94                 this.show();
95             }, panel);
96             this.on('hide', panel.hide, panel);
97             this.on('assignablerolesloaded', this.updateContent, this, panel);
98             this.on('cohortsloaded', this.updateContent, this, panel);
99             this.on('defaultcohortroleloaded', this.updateContent, this, panel);
100             Y.on('key', this.hide, document.body, 'down:27', this);
101             close.on('click', this.hide, this);
103             Y.all('.enrol_cohort_plugin input').each(function(node){
104                 if (node.getAttribute('type', 'submit')) {
105                     node.on('click', this.show, this);
106                 }
107             }, this);
109             base = panel.get('boundingBox');
110             base.plug(Y.Plugin.Drag);
111             base.dd.addHandle('.yui3-widget-hd h2');
112             base.one('.yui3-widget-hd h2').setStyle('cursor', 'move');
113         },
114         show : function(e) {
115             e.preventDefault();
116             // prepare the data and display the window
117             this.getCohorts(e, false);
118             this.getAssignableRoles();
119             this.fire('show');
120         },
121         updateContent : function(e, panel) {
122             var content, i, roles, cohorts, count=0, supportmanual = this.get(MANUALENROLMENT), defaultrole;
123             switch (e.type.replace(/^[^:]+:/, '')) {
124                 case 'cohortsloaded' :
125                     if (this.get(FIRSTPAGE)) {
126                         // we are on the page 0, create new element for cohorts list
127                         content = Y.Node.create('<div class="'+CSS.COHORTS+'"></div>');
128                         if (supportmanual) {
129                             content.addClass(CSS.ENROLUSERS);
130                         }
131                     } else {
132                         // we are adding cohorts to existing list
133                         content = Y.Node.one('.'+CSS.PANELCOHORTS+' .'+CSS.COHORTS);
134                         content.one('.'+CSS.MORERESULTS).remove();
135                     }
136                     // add cohorts items to the content
137                     cohorts = this.get(COHORTS);
138                     for (i in cohorts) {
139                         count++;
140                         cohorts[i].on('enrolchort', this.enrolCohort, this, cohorts[i], panel.get('contentBox'), false);
141                         cohorts[i].on('enrolusers', this.enrolCohort, this, cohorts[i], panel.get('contentBox'), true);
142                         content.append(cohorts[i].toHTML(supportmanual).addClass((count%2)?'even':'odd'));
143                     }
144                     // add the next link if there are more items expected
145                     if (this.get(MORERESULTS)) {
146                         var fetchmore = Y.Node.create('<div class="'+CSS.MORERESULTS+'"><a href="#">'+M.str.enrol_cohort.ajaxmore+'</a></div>');
147                         fetchmore.on('click', this.getCohorts, this, true);
148                         content.append(fetchmore);
149                     }
150                     // finally assing the content to the block
151                     if (this.get(FIRSTPAGE)) {
152                         panel.get('contentBox').one('.'+CSS.PANELCOHORTS).setContent(content);
153                     }
154                     break;
155                 case 'assignablerolesloaded':
156                     roles = this.get(ASSIGNABLEROLES);
157                     content = Y.Node.create('<select></select>');
158                     for (i in roles) {
159                         content.append(Y.Node.create('<option value="'+i+'">'+roles[i]+'</option>'));
160                     }
161                     panel.get('contentBox').one('.'+CSS.PANELROLES).setContent(Y.Node.create('<div><label>'+M.str.role.assignroles+':</label></div>').append(content));
163                     this.getDefaultCohortRole();
164                     break;
165                 case 'defaultcohortroleloaded':
166                     defaultrole = this.get(DEFAULTCOHORTROLE);
167                     panel.get('contentBox').one('.'+CSS.PANELROLES+' select').set('value', defaultrole);
168                     break;
169             }
170         },
171         hide : function() {
172             if (this.get(REQUIREREFRESH)) {
173                 window.location = this.get(URL);
174             }
175             this.fire('hide');
176         },
177         getCohorts : function(e, append) {
178             if (e) {
179                 e.preventDefault();
180             }
181             if (append) {
182                 this.set(FIRSTPAGE, false);
183             } else {
184                 this.set(FIRSTPAGE, true);
185                 this.set(OFFSET, 0);
186             }
187             var params = [];
188             params['id'] = this.get(COURSEID);
189             params['offset'] = this.get(OFFSET);
190             params['search'] = this.get(SEARCH).get('value');
191             params['action'] = 'getcohorts';
192             params['sesskey'] = M.cfg.sesskey;
194             Y.io(M.cfg.wwwroot+this.get(AJAXURL), {
195                 method:'POST',
196                 data:build_querystring(params),
197                 on: {
198                     complete: function(tid, outcome, args) {
199                         try {
200                             var cohorts = Y.JSON.parse(outcome.responseText);
201                             if (cohorts.error) {
202                                 new M.core.ajaxException(cohorts);
203                             } else {
204                                 this.setCohorts(cohorts.response);
205                             }
206                         } catch (e) {
207                             return new M.core.exception(e);
208                         }
209                         this.fire('cohortsloaded');
210                     }
211                 },
212                 context:this
213             });
214         },
215         setCohorts : function(response) {
216             this.set(MORERESULTS, response.more);
217             this.set(OFFSET, response.offset);
218             var rawcohorts = response.cohorts;
219             var cohorts = [], i=0;
220             for (i in rawcohorts) {
221                 cohorts[rawcohorts[i].cohortid] = new COHORT(rawcohorts[i]);
222             }
223             this.set(COHORTS, cohorts);
224         },
225         getAssignableRoles : function() {
226             Y.io(M.cfg.wwwroot+this.get(AJAXURL), {
227                 method:'POST',
228                 data:'id='+this.get(COURSEID)+'&action=getassignable&sesskey='+M.cfg.sesskey,
229                 on: {
230                     complete: function(tid, outcome, args) {
231                         try {
232                             var roles = Y.JSON.parse(outcome.responseText);
233                             this.set(ASSIGNABLEROLES, roles.response);
234                         } catch (e) {
235                             return new M.core.exception(e);
236                         }
237                         this.getAssignableRoles = function() {
238                             this.fire('assignablerolesloaded');
239                         };
240                         this.getAssignableRoles();
241                     }
242                 },
243                 context:this
244             });
245         },
246         getDefaultCohortRole : function() {
247             Y.io(M.cfg.wwwroot+this.get(AJAXURL), {
248                 method:'POST',
249                 data:'id='+this.get(COURSEID)+'&action=getdefaultcohortrole&sesskey='+M.cfg.sesskey,
250                 on: {
251                     complete: function(tid, outcome, args) {
252                         try {
253                             var roles = Y.JSON.parse(outcome.responseText);
254                             this.set(DEFAULTCOHORTROLE, roles.response);
255                         } catch (e) {
256                             return new M.core.exception(e);
257                         }
258                         this.fire('defaultcohortroleloaded');
259                     }
260                 },
261                 context:this
262             });
263         },
264         enrolCohort : function(e, cohort, node, usersonly) {
265             var params = {
266                 id : this.get(COURSEID),
267                 roleid : node.one('.'+CSS.PANELROLES+' select').get('value'),
268                 cohortid : cohort.get(COHORTID),
269                 action : (usersonly)?'enrolcohortusers':'enrolcohort',
270                 sesskey : M.cfg.sesskey
271             };
272             Y.io(M.cfg.wwwroot+this.get(AJAXURL), {
273                 method:'POST',
274                 data:build_querystring(params),
275                 on: {
276                     complete: function(tid, outcome, args) {
277                         try {
278                             var result = Y.JSON.parse(outcome.responseText);
279                             if (result.error) {
280                                 new M.core.ajaxException(result);
281                             } else {
282                                 if (result.response && result.response.message) {
283                                     new M.core.alert(result.response);
284                                 }
285                                 var enrolled = Y.Node.create('<div class="'+CSS.COHORTBUTTON+' alreadyenrolled">'+M.str.enrol.synced+'</div>');
286                                 node.one('.'+CSS.COHORT+' #cohortid_'+cohort.get(COHORTID)).replace(enrolled);
287                                 this.set(REQUIREREFRESH, true);
288                             }
289                         } catch (e) {
290                             new M.core.exception(e);
291                         }
292                     }
293                 },
294                 context:this
295             });
296             return true;
297         }
298     };
299     Y.extend(CONTROLLER, Y.Base, CONTROLLER.prototype, {
300         NAME : CONTROLLERNAME,
301         ATTRS : {
302             url : {
303                 validator : Y.Lang.isString
304             },
305             ajaxurl : {
306                 validator : Y.Lang.isString
307             },
308             courseid : {
309                 value : null
310             },
311             cohorts : {
312                 validator : Y.Lang.isArray,
313                 value : null
314             },
315             assignableRoles : {
316                 value : null
317             },
318             manualEnrolment : {
319                 value : false
320             },
321             defaultCohortRole : {
322                 value : null
323             },
324             requiresRefresh : {
325                 value : false,
326                 validator : Y.Lang.isBool
327             }
328         }
329     });
330     Y.augment(CONTROLLER, Y.EventTarget);
332     var COHORT = function(config) {
333         COHORT.superclass.constructor.apply(this, arguments);
334     };
335     Y.extend(COHORT, Y.Base, {
336         toHTML : function(supportmanualenrolment){
337             var button, result, name, users, syncbutton, usersbutton;
338             result = Y.Node.create('<div class="'+CSS.COHORT+'"></div>');
339             if (this.get(ENROLLED)) {
340                 button = Y.Node.create('<div class="'+CSS.COHORTBUTTON+' alreadyenrolled">'+M.str.enrol.synced+'</div>');
341             } else {
342                 button = Y.Node.create('<div id="cohortid_'+this.get(COHORTID)+'"></div>');
344                 syncbutton = Y.Node.create('<a class="'+CSS.COHORTBUTTON+' notenrolled enrolcohort">'+M.str.enrol.enrolcohort+'</a>');
345                 syncbutton.on('click', function(){this.fire('enrolchort');}, this);
346                 button.append(syncbutton);
348                 if (supportmanualenrolment) {
349                     usersbutton = Y.Node.create('<a class="'+CSS.COHORTBUTTON+' notenrolled enrolusers">'+M.str.enrol.enrolcohortusers+'</a>');
350                     usersbutton.on('click', function(){this.fire('enrolusers');}, this);
351                     button.append(usersbutton);
352                 }
353             }
354             name = Y.Node.create('<div class="'+CSS.COHORTNAME+'">'+this.get(NAME)+'</div>');
355             users = Y.Node.create('<div class="'+CSS.COHORTUSERS+'">'+this.get(USERS)+'</div>');
356             return result.append(button).append(name).append(users);
357         }
358     }, {
359         NAME : COHORTNAME,
360         ATTRS : {
361             cohortid : {
363             },
364             name : {
365                 validator : Y.Lang.isString
366             },
367             enrolled : {
368                 value : false
369             },
370             users : {
371                 value : 0
372             }
373         }
374     });
375     Y.augment(COHORT, Y.EventTarget);
377     M.enrol_cohort = M.enrol || {};
378     M.enrol_cohort.quickenrolment = {
379         init : function(cfg) {
380             new CONTROLLER(cfg);
381         }
382     }
384 }, '@VERSION@', {requires:['base','node', 'overlay', 'io-base', 'test', 'json-parse', 'event-delegate', 'dd-plugin', 'event-key', 'moodle-core-notification']});