Merge branch 'MDL-33073-master-1' of git://git.luns.net.uk/moodle
[moodle.git] / course / yui / toolboxes / toolboxes.js
CommitLineData
ebaa29d1
ARN
1YUI.add('moodle-course-toolboxes', function(Y) {
2 WAITICON = {'pix':"i/loading_small",'component':'moodle'};
3 // The CSS selectors we use
4 var CSS = {
5 ACTIVITYLI : 'li.activity',
537194ff 6 COMMANDSPAN : 'span.commands',
b3c35188 7 SPINNERCOMMANDSPAN : 'span.commands',
eac3ed52 8 CONTENTAFTERLINK : 'div.contentafterlink',
ebaa29d1
ARN
9 DELETE : 'a.editing_delete',
10 DIMCLASS : 'dimmed',
eac3ed52 11 DIMMEDTEXT : 'dimmed_text',
7a9a07d2 12 EDITTITLE : 'a.editing_title',
ebaa29d1
ARN
13 EDITTITLECLASS : 'edittitle',
14 GENERICICONCLASS : 'iconsmall',
15 GROUPSNONE : 'a.editing_groupsnone',
16 GROUPSSEPARATE : 'a.editing_groupsseparate',
17 GROUPSVISIBLE : 'a.editing_groupsvisible',
18 HASLABEL : 'label',
19 HIDE : 'a.editing_hide',
20 HIGHLIGHT : 'a.editing_highlight',
21 INSTANCENAME : 'span.instancename',
22 LIGHTBOX : 'lightbox',
23 MODINDENTCOUNT : 'mod-indent-',
24 MODINDENTDIV : 'div.mod-indent',
95ef704d 25 MODINDENTHUGE : 'mod-indent-huge',
ebaa29d1
ARN
26 MODULEIDPREFIX : 'module-',
27 MOVELEFT : 'a.editing_moveleft',
28 MOVELEFTCLASS : 'editing_moveleft',
29 MOVERIGHT : 'a.editing_moveright',
30 PAGECONTENT : 'div#page-content',
31 RIGHTDIV : 'div.right',
32 SECTIONHIDDENCLASS : 'hidden',
33 SECTIONIDPREFIX : 'section-',
34 SECTIONLI : 'li.section',
35 SHOW : 'a.editing_show',
36 SHOWHIDE : 'a.editing_showhide'
37 };
38
39 /**
40 * The toolbox classes
41 *
42 * TOOLBOX is a generic class which should never be directly instantiated
43 * RESOURCETOOLBOX is a class extending TOOLBOX containing code specific to resources
44 * SECTIONTOOLBOX is a class extending TOOLBOX containing code specific to sections
45 */
46 var TOOLBOX = function() {
47 TOOLBOX.superclass.constructor.apply(this, arguments);
48 }
49
50 Y.extend(TOOLBOX, Y.Base, {
51 /**
52 * Replace the button click at the selector with the specified
53 * callback
54 *
55 * @param toolboxtarget The selector of the working area
56 * @param selector The 'button' to replace
57 * @param callback The callback to apply
58 * @param cursor An optional cursor style to apply
59 */
60 replace_button : function(toolboxtarget, selector, callback, cursor) {
61 if (!cursor) {
62 // Set the default cursor type to pointer to match the
63 // anchor
64 cursor = 'pointer';
65 }
66 var button = Y.one(toolboxtarget).all(selector)
ebaa29d1
ARN
67 .setStyle('cursor', cursor);
68
69 // on isn't chainable and will return an event
70 button.on('click', callback, this);
71
72 return button;
73 },
74 /**
75 * Toggle the visibility and availability for the specified
76 * resource show/hide button
77 */
78 toggle_hide_resource_ui : function(button) {
79 var element = button.ancestor(CSS.ACTIVITYLI);
80 var hideicon = button.one('img');
81
82 var dimarea;
83 var toggle_class;
84 if (this.is_label(element)) {
eac3ed52 85 toggle_class = CSS.DIMMEDTEXT;
ebaa29d1
ARN
86 dimarea = element.one(CSS.MODINDENTDIV + ' div');
87 } else {
88 toggle_class = CSS.DIMCLASS;
89 dimarea = element.one('a');
90 }
91
92 var status = '';
93 var value;
94 if (dimarea.hasClass(toggle_class)) {
95 status = 'hide';
96 value = 1;
97 } else {
98 status = 'show';
99 value = 0;
100 }
101
102 // Change the UI
103 dimarea.toggleClass(toggle_class);
eac3ed52
ARN
104 // We need to toggle dimming on the description too
105 element.all(CSS.CONTENTAFTERLINK).toggleClass(CSS.DIMMEDTEXT);
ebaa29d1
ARN
106 var newstring = M.util.get_string(status, 'moodle');
107 hideicon.setAttrs({
108 'alt' : newstring,
109 'title' : newstring,
110 'src' : M.util.image_url('t/' + status)
111 });
112 button.set('title', newstring);
113 button.set('className', 'editing_'+status);
114
115 return value;
116 },
117 /**
118 * Send a request using the REST API
119 *
120 * @param data The data to submit
45b364b9 121 * @param statusspinner (optional) A statusspinner which may contain a section loader
ebaa29d1
ARN
122 * @param optionalconfig (optional) Any additional configuration to submit
123 * @return response responseText field from responce
124 */
45b364b9 125 send_request : function(data, statusspinner, optionalconfig) {
ebaa29d1
ARN
126 // Default data structure
127 if (!data) {
128 data = {};
129 }
130 // Handle any variables which we must pass back through to
131 var pageparams = this.get('config').pageparams;
132 for (varname in pageparams) {
133 data[varname] = pageparams[varname];
134 }
135
ebaa29d1
ARN
136 data.sesskey = M.cfg.sesskey;
137 data.courseId = this.get('courseid');
138
139 var uri = M.cfg.wwwroot + this.get('ajaxurl');
140
141 // Define the configuration to send with the request
142 var responsetext = [];
143 var config = {
144 method: 'POST',
145 data: data,
146 on: {
147 success: function(tid, response) {
148 try {
149 responsetext = Y.JSON.parse(response.responseText);
150 if (responsetext.error) {
151 new M.core.ajaxException(responsetext);
152 }
153 } catch (e) {}
45b364b9 154 if (statusspinner) {
ebaa29d1 155 window.setTimeout(function(e) {
45b364b9
ARN
156 statusspinner.hide();
157 }, 400);
ebaa29d1
ARN
158 }
159 },
160 failure : function(tid, response) {
45b364b9
ARN
161 if (statusspinner) {
162 statusspinner.hide();
ebaa29d1
ARN
163 }
164 new M.core.ajaxException(response);
165 }
166 },
167 context: this,
168 sync: true
169 }
170
171 // Apply optional config
172 if (optionalconfig) {
173 for (varname in optionalconfig) {
174 config[varname] = optionalconfig[varname];
175 }
176 }
177
45b364b9
ARN
178 if (statusspinner) {
179 statusspinner.show();
ebaa29d1
ARN
180 }
181
182 // Send the request
183 Y.io(uri, config);
184 return responsetext;
185 },
186 is_label : function(target) {
187 return target.hasClass(CSS.HASLABEL);
188 },
189 /**
190 * Return the module ID for the specified element
191 *
192 * @param element The <li> element to determine a module-id number for
193 * @return string The module ID
194 */
195 get_element_id : function(element) {
196 return element.get('id').replace(CSS.MODULEIDPREFIX, '');
197 },
198 /**
199 * Return the module ID for the specified element
200 *
201 * @param element The <li> element to determine a module-id number for
202 * @return string The module ID
203 */
204 get_section_id : function(section) {
205 return section.get('id').replace(CSS.SECTIONIDPREFIX, '');
ebaa29d1
ARN
206 }
207 },
208 {
209 NAME : 'course-toolbox',
210 ATTRS : {
211 // The ID of the current course
212 courseid : {
213 'value' : 0
214 },
215 ajaxurl : {
216 'value' : 0
217 },
218 config : {
219 'value' : 0
220 }
221 }
222 }
223 );
224
225
226 var RESOURCETOOLBOX = function() {
227 RESOURCETOOLBOX.superclass.constructor.apply(this, arguments);
228 }
229
230 Y.extend(RESOURCETOOLBOX, TOOLBOX, {
231 // Variables
232 GROUPS_NONE : 0,
233 GROUPS_SEPARATE : 1,
234 GROUPS_VISIBLE : 2,
235
236 /**
237 * Initialize the resource toolbox
238 *
239 * Updates all span.commands with relevant handlers and other required changes
240 */
241 initializer : function(config) {
242 this.setup_for_resource();
243 M.course.coursebase.register_module(this);
244 },
245
246 /**
247 * Update any span.commands within the scope of the specified
248 * selector with AJAX equivelants
249 *
250 * @param baseselector The selector to limit scope to
251 * @return void
252 */
253 setup_for_resource : function(baseselector) {
254 if (!baseselector) {
537194ff 255 var baseselector = CSS.PAGECONTENT + ' ' + CSS.ACTIVITYLI;;
ebaa29d1
ARN
256 }
257
258 Y.all(baseselector).each(this._setup_for_resource, this);
259 },
260 _setup_for_resource : function(toolboxtarget) {
7a9a07d2
ARN
261 // Edit Title
262 this.replace_button(toolboxtarget, CSS.COMMANDSPAN + ' ' + CSS.EDITTITLE, this.edit_resource_title);
263
ebaa29d1
ARN
264 // Move left and right
265 this.replace_button(toolboxtarget, CSS.COMMANDSPAN + ' ' + CSS.MOVELEFT, this.move_left);
266 this.replace_button(toolboxtarget, CSS.COMMANDSPAN + ' ' + CSS.MOVERIGHT, this.move_right);
267
268 // Delete
269 this.replace_button(toolboxtarget, CSS.COMMANDSPAN + ' ' + CSS.DELETE, this.delete_resource);
270
271 // Show/Hide
272 var showhide = this.replace_button(toolboxtarget, CSS.COMMANDSPAN + ' ' + CSS.HIDE, this.toggle_hide_resource);
273 var shown = this.replace_button(toolboxtarget, CSS.COMMANDSPAN + ' ' + CSS.SHOW, this.toggle_hide_resource);
274
275 showhide = showhide.concat(shown);
276 showhide.each(function(node) {
277 var section = node.ancestor(CSS.SECTIONLI);
278 if (section && section.hasClass(CSS.SECTIONHIDDENCLASS)) {
279 node.setStyle('cursor', 'auto');
280 }
281 });
282
283 // Change Group Mode
284 var groups;
285 groups = this.replace_button(toolboxtarget, CSS.COMMANDSPAN + ' ' + CSS.GROUPSNONE, this.toggle_groupmode);
286 groups.setAttribute('groupmode', this.GROUPS_NONE);
287
288 groups = this.replace_button(toolboxtarget, CSS.COMMANDSPAN + ' ' + CSS.GROUPSSEPARATE, this.toggle_groupmode);
289 groups.setAttribute('groupmode', this.GROUPS_SEPARATE);
290
291 groups = this.replace_button(toolboxtarget, CSS.COMMANDSPAN + ' ' + CSS.GROUPSVISIBLE, this.toggle_groupmode);
292 groups.setAttribute('groupmode', this.GROUPS_VISIBLE);
293 },
294 move_left : function(e) {
45b364b9 295 this.move_leftright(e, -1);
ebaa29d1
ARN
296 },
297 move_right : function(e) {
45b364b9 298 this.move_leftright(e, 1);
ebaa29d1 299 },
45b364b9 300 move_leftright : function(e, direction) {
5bd03e12
ARN
301 // Prevent the default button action
302 e.preventDefault();
303
ebaa29d1
ARN
304 // Get the element we're working on
305 var element = e.target.ancestor(CSS.ACTIVITYLI);
306
307 // And we need to determine the current and new indent level
308 var indentdiv = element.one(CSS.MODINDENTDIV);
309 var indent = indentdiv.getAttribute('class').match(/mod-indent-(\d{1,})/);
310
311 if (indent) {
312 var oldindent = parseInt(indent[1]);
313 var newindent = Math.max(0, (oldindent + parseInt(direction)));
314 indentdiv.removeClass(indent[0]);
315 } else {
316 var oldindent = 0;
317 var newindent = 1;
318 }
319
320 // Perform the move
321 indentdiv.addClass(CSS.MODINDENTCOUNT + newindent);
322 var data = {
323 'class' : 'resource',
324 'field' : 'indent',
325 'value' : newindent,
326 'id' : this.get_element_id(element)
327 };
b3c35188 328 var spinner = M.util.add_spinner(Y, element.one(CSS.SPINNERCOMMANDSPAN));
45b364b9 329 this.send_request(data, spinner);
ebaa29d1
ARN
330
331 // Handle removal/addition of the moveleft button
332 if (newindent == 0) {
45b364b9 333 element.one(CSS.MOVELEFT).remove();
ebaa29d1
ARN
334 } else if (newindent == 1 && oldindent == 0) {
335 this.add_moveleft(element);
336 }
95ef704d
ARN
337
338 // Handle massive indentation to match non-ajax display
339 var hashugeclass = indentdiv.hasClass(CSS.MODINDENTHUGE);
340 if (newindent > 15 && !hashugeclass) {
341 indentdiv.addClass(CSS.MODINDENTHUGE);
342 } else if (newindent <= 15 && hashugeclass) {
343 indentdiv.removeClass(CSS.MODINDENTHUGE);
344 }
ebaa29d1
ARN
345 },
346 delete_resource : function(e) {
5bd03e12
ARN
347 // Prevent the default button action
348 e.preventDefault();
349
ebaa29d1
ARN
350 // Get the element we're working on
351 var element = e.target.ancestor(CSS.ACTIVITYLI);
352
353 var confirmstring = '';
354 if (this.is_label(element)) {
355 // Labels are slightly different to other activities
356 var plugindata = {
357 type : M.util.get_string('pluginname', 'label')
358 }
359 confirmstring = M.util.get_string('deletechecktype', 'moodle', plugindata)
360 } else {
361 var plugindata = {
362 type : M.util.get_string('pluginname', element.getAttribute('class').match(/modtype_([^\s]*)/)[1]),
363 name : element.one(CSS.INSTANCENAME).get('firstChild').get('data')
364 }
365 confirmstring = M.util.get_string('deletechecktypename', 'moodle', plugindata);
366 }
367
368 // Confirm element removal
369 if (!confirm(confirmstring)) {
370 return false;
371 }
372
373 // Actually remove the element
374 element.remove();
375 var data = {
376 'class' : 'resource',
377 'action' : 'DELETE',
378 'id' : this.get_element_id(element)
379 };
380 this.send_request(data);
381 },
382 toggle_hide_resource : function(e) {
5bd03e12
ARN
383 // Prevent the default button action
384 e.preventDefault();
385
ebaa29d1
ARN
386 // Return early if the current section is hidden
387 var section = e.target.ancestor(CSS.SECTIONLI);
388 if (section && section.hasClass(CSS.SECTIONHIDDENCLASS)) {
389 return;
390 }
391
392 // Get the element we're working on
393 var element = e.target.ancestor(CSS.ACTIVITYLI);
394
395 var button = e.target.ancestor('a', true);
396
397 var value = this.toggle_hide_resource_ui(button);
398
399 // Send the request
400 var data = {
401 'class' : 'resource',
402 'field' : 'visible',
403 'value' : value,
404 'id' : this.get_element_id(element)
405 };
b3c35188 406 var spinner = M.util.add_spinner(Y, element.one(CSS.SPINNERCOMMANDSPAN));
45b364b9 407 this.send_request(data, spinner);
ebaa29d1
ARN
408 },
409 toggle_groupmode : function(e) {
5bd03e12
ARN
410 // Prevent the default button action
411 e.preventDefault();
412
ebaa29d1
ARN
413 // Get the element we're working on
414 var element = e.target.ancestor(CSS.ACTIVITYLI);
415
416 var button = e.target.ancestor('a', true);
417 var icon = button.one('img');
418
419 // Current Mode
420 var groupmode = button.getAttribute('groupmode');
421 groupmode++;
422 if (groupmode > 2) {
423 groupmode = 0;
424 }
425 button.setAttribute('groupmode', groupmode);
426
427 var newtitle = '';
428 var iconsrc = '';
429 switch (groupmode) {
430 case this.GROUPS_NONE:
431 newtitle = 'groupsnone';
432 iconsrc = M.util.image_url('t/groupn');
433 break;
434 case this.GROUPS_SEPARATE:
435 newtitle = 'groupsseparate';
436 iconsrc = M.util.image_url('t/groups');
437 break;
438 case this.GROUPS_VISIBLE:
439 newtitle = 'groupsvisible';
440 iconsrc = M.util.image_url('t/groupv');
441 break;
442 }
443 newtitle = M.util.get_string('clicktochangeinbrackets', 'moodle',
444 M.util.get_string(newtitle, 'moodle'));
445
446 // Change the UI
447 icon.setAttrs({
448 'alt' : newtitle,
449 'title' : newtitle,
450 'src' : iconsrc
451 });
452 button.setAttribute('title', newtitle);
453
454 // And send the request
455 var data = {
456 'class' : 'resource',
457 'field' : 'groupmode',
458 'value' : groupmode,
459 'id' : this.get_element_id(element)
460 };
b3c35188 461 var spinner = M.util.add_spinner(Y, element.one(CSS.SPINNERCOMMANDSPAN));
45b364b9 462 this.send_request(data, spinner);
ebaa29d1
ARN
463 },
464 /**
465 * Add the moveleft button
466 * This is required after moving left from an initial position of 0
467 *
468 * @param target The encapsulating <li> element
469 */
470 add_moveleft : function(target) {
471 var left_string = M.util.get_string('moveleft', 'moodle');
472 var newicon = Y.Node.create('<img />')
473 .addClass(CSS.GENERICICONCLASS)
474 .setAttrs({
475 'src' : M.util.image_url('t/left', 'moodle'),
476 'title' : left_string,
477 'alt' : left_string
478 });
5bd03e12
ARN
479 var moveright = target.one(CSS.MOVERIGHT);
480 var newlink = moveright.getAttribute('href').replace('indent=1', 'indent=-1');
ebaa29d1
ARN
481 var anchor = new Y.Node.create('<a />')
482 .setStyle('cursor', 'pointer')
483 .addClass(CSS.MOVELEFTCLASS)
5bd03e12
ARN
484 .setAttribute('href', newlink)
485 .setAttribute('title', left_string);
ebaa29d1
ARN
486 anchor.appendChild(newicon);
487 anchor.on('click', this.move_left, this);
5bd03e12 488 moveright.insert(anchor, 'before');
7a9a07d2
ARN
489 },
490 /**
491 * Edit the title for the resource
492 */
493 edit_resource_title : function(e) {
494 // Get the element we're working on
495 var element = e.target.ancestor(CSS.ACTIVITYLI);
496 var instancename = element.one(CSS.INSTANCENAME);
497 var currenttitle = instancename.get('firstChild');
498 var oldtitle = currenttitle.get('data');
499 var titletext = oldtitle;
500 var editbutton = element.one('a.' + CSS.EDITTITLECLASS + ' img');
501
502 // Disable the current href to prevent redirections when editing
503 var anchor = instancename.ancestor('a');
504 anchor.setAttribute('oldhref', anchor.getAttribute('href'));
505 anchor.removeAttribute('href');
506
507 var data = {
508 'class' : 'resource',
509 'field' : 'gettitle',
510 'id' : this.get_element_id(element)
511 };
512
513 // Try to retrieve the existing string from the server
514 var response = this.send_request(data, editbutton);
515 if (response.instancename) {
516 titletext = response.instancename;
517 }
518
519 // Create the editor and submit button
520 var editor = Y.Node.create('<input />')
521 .setAttrs({
522 'name' : 'title',
523 'value' : titletext,
524 'autocomplete' : 'off'
525 })
526 .addClass('titleeditor');
527 var editform = Y.Node.create('<form />')
528 .setStyle('padding', '0')
529 .setStyle('display', 'inline')
530 .setAttribute('action', '#');
531
532 var editinstructions = Y.Node.create('<span />')
533 .addClass('editinstructions')
534 .set('innerHTML', M.util.get_string('edittitleinstructions', 'moodle'));
535
536 // Clear the existing content and put the editor in
537 currenttitle.set('data', '');
538 editform.appendChild(editor);
539 instancename.appendChild(editform);
540 element.appendChild(editinstructions);
541 e.preventDefault();
542
543 // Focus and select the editor text
544 editor.focus().select();
545
546 // Handle cancellation of the editor
547 editor.on('blur', function(e) {
548 // Detach the blur event before removing as some actions trigger multiple blurs in
549 // some browser
550 editor.detach('blur');
551 editform.remove();
552 editinstructions.remove();
553
554 // Set the title and anchor back to their previous settings
555 currenttitle.set('data', oldtitle);
556 anchor.setAttribute('href', anchor.getAttribute('oldhref'));
557 anchor.removeAttribute('oldhref');
558 });
559
560 // Handle form submission
561 editform.on('submit', function(e) {
562 // We don't actually want to submit anything
563 e.preventDefault();
564
565 // Detach the handlers to prevent multiple submissions
566 editform.detach('submit');
567 editor.detach('blur');
568
569 // We only accept strings which have valid content
570 var newtitle = Y.Lang.trim(editor.get('value'));
571 if (newtitle != null && newtitle != "" && newtitle != titletext) {
572 var data = {
573 'class' : 'resource',
574 'field' : 'updatetitle',
575 'title' : newtitle,
576 'id' : this.get_element_id(element)
577 };
578 var response = this.send_request(data, editbutton);
579 if (response.instancename) {
580 currenttitle.set('data', response.instancename);
581 }
582 } else {
583 // Invalid content. Set the title back to it's original contents
584 currenttitle.set('data', oldtitle);
585 }
586
587 editform.remove();
588 editinstructions.remove();
589
590 // We need a timeout here otherwise hitting return to save in some browsers triggers
591 // the anchor
592 setTimeout(function(e) {
593 anchor.setAttribute('href', anchor.getAttribute('oldhref'));
594 anchor.removeAttribute('oldhref');
595 }, 500);
596 }, this);
ebaa29d1
ARN
597 }
598 }, {
599 NAME : 'course-resource-toolbox',
600 ATTRS : {
601 courseid : {
602 'value' : 0
603 },
604 format : {
605 'value' : 'topics'
606 }
607 }
608 });
609
610 var SECTIONTOOLBOX = function() {
611 SECTIONTOOLBOX.superclass.constructor.apply(this, arguments);
612 }
613
614 Y.extend(SECTIONTOOLBOX, TOOLBOX, {
615 /**
616 * Initialize the toolboxes module
617 *
618 * Updates all span.commands with relevant handlers and other required changes
619 */
620 initializer : function(config) {
621 this.setup_for_section();
622 M.course.coursebase.register_module(this);
623 },
624 /**
625 * Update any section areas within the scope of the specified
626 * selector with AJAX equivelants
627 *
628 * @param baseselector The selector to limit scope to
629 * @return void
630 */
631 setup_for_section : function(baseselector) {
632 if (!baseselector) {
633 var baseselector = CSS.PAGECONTENT;
634 }
635
636 Y.all(baseselector).each(this._setup_for_section, this);
637 },
638 _setup_for_section : function(toolboxtarget) {
639 // Section Highlighting
640 this.replace_button(toolboxtarget, CSS.RIGHTDIV + ' ' + CSS.HIGHLIGHT, this.toggle_highlight);
641
642 // Section Visibility
643 this.replace_button(toolboxtarget, CSS.RIGHTDIV + ' ' + CSS.SHOWHIDE, this.toggle_hide_section);
644 },
645 toggle_hide_section : function(e) {
5bd03e12
ARN
646 // Prevent the default button action
647 e.preventDefault();
648
ebaa29d1
ARN
649 // Get the section we're working on
650 var section = e.target.ancestor(CSS.SECTIONLI);
651 var button = e.target.ancestor('a', true);
652 var hideicon = button.one('img');
653
654 // The value to submit
655 var value;
656 // The status text for strings and images
657 var status;
658
659 if (!section.hasClass(CSS.SECTIONHIDDENCLASS)) {
660 section.addClass(CSS.SECTIONHIDDENCLASS);
661 value = 0;
662 status = 'show';
663
664 } else {
665 section.removeClass(CSS.SECTIONHIDDENCLASS);
666 value = 1;
667 status = 'hide';
668 }
669
670 var newstring = M.util.get_string(status + 'fromothers', 'format_' + this.get('format'));
671 hideicon.setAttrs({
672 'alt' : newstring,
673 'title' : newstring,
674 'src' : M.util.image_url('i/' + status)
675 });
676 button.set('title', newstring);
677
678 // Change the highlight status
679 var data = {
680 'class' : 'section',
681 'field' : 'visible',
682 'id' : this.get_section_id(section),
683 'value' : value
684 };
685
6a14c4ff 686 var lightbox = M.util.add_lightbox(Y, section);
ebaa29d1
ARN
687 lightbox.show();
688
45b364b9 689 var response = this.send_request(data, lightbox);
ebaa29d1
ARN
690
691 var activities = section.all(CSS.ACTIVITYLI);
692 activities.each(function(node) {
693 if (node.one(CSS.SHOW)) {
694 var button = node.one(CSS.SHOW);
695 } else {
696 var button = node.one(CSS.HIDE);
697 }
698 var activityid = this.get_element_id(node);
699
700 if (Y.Array.indexOf(response.resourcestotoggle, activityid) != -1) {
701 this.toggle_hide_resource_ui(button);
702 }
703
704 if (value == 0) {
705 button.setStyle('cursor', 'auto');
706 } else {
707 button.setStyle('cursor', 'pointer');
708 }
709 }, this);
710 },
711 toggle_highlight : function(e) {
5bd03e12
ARN
712 // Prevent the default button action
713 e.preventDefault();
714
ebaa29d1
ARN
715 // Get the section we're working on
716 var section = e.target.ancestor(CSS.SECTIONLI);
717 var button = e.target.ancestor('a', true);
718 var buttonicon = button.one('img');
719
720 // Determine whether the marker is currently set
721 var togglestatus = section.hasClass('current');
722 var value = 0;
723
724 // Set the current highlighted item text
725 var old_string = M.util.get_string('markthistopic', 'moodle');
726 Y.one(CSS.PAGECONTENT)
727 .all(CSS.SECTIONLI + '.current ' + CSS.HIGHLIGHT)
728 .set('title', old_string);
729 Y.one(CSS.PAGECONTENT)
730 .all(CSS.SECTIONLI + '.current ' + CSS.HIGHLIGHT + ' img')
731 .set('title', old_string)
732 .set('alt', old_string)
733 .set('src', M.util.image_url('i/marker'));
734
735 // Remove the highlighting from all sections
736 var allsections = Y.one(CSS.PAGECONTENT).all(CSS.SECTIONLI)
737 .removeClass('current');
738
739 // Then add it if required to the selected section
740 if (!togglestatus) {
741 section.addClass('current');
742 value = this.get_section_id(section);
743 var new_string = M.util.get_string('markedthistopic', 'moodle');
744 button
745 .set('title', new_string);
746 buttonicon
747 .set('title', new_string)
748 .set('alt', new_string)
749 .set('src', M.util.image_url('i/marked'));
750 }
751
752 // Change the highlight status
753 var data = {
754 'class' : 'course',
755 'field' : 'marker',
756 'value' : value
757 };
6a14c4ff 758 var lightbox = M.util.add_lightbox(Y, section);
ebaa29d1 759 lightbox.show();
45b364b9 760 this.send_request(data, lightbox);
ebaa29d1
ARN
761 }
762 }, {
763 NAME : 'course-section-toolbox',
764 ATTRS : {
765 courseid : {
766 'value' : 0
767 },
768 format : {
769 'value' : 'topics'
770 }
771 }
772 });
773
774 M.course = M.course || {};
775
776 M.course.init_resource_toolbox = function(config) {
777 return new RESOURCETOOLBOX(config);
778 };
779
780 M.course.init_section_toolbox = function(config) {
781 return new SECTIONTOOLBOX(config);
782 };
783
784},
785'@VERSION@', {
786 requires : ['base', 'node', 'io', 'moodle-course-coursebase']
787}
788);