mirror of
https://github.com/moodle/moodle.git
synced 2025-03-13 20:26:32 +01:00
795 lines
30 KiB
JavaScript
795 lines
30 KiB
JavaScript
YUI.add('moodle-course-toolboxes', function(Y) {
|
|
WAITICON = {'pix':"i/loading_small",'component':'moodle'};
|
|
// The CSS selectors we use
|
|
var CSS = {
|
|
ACTIVITYLI : 'li.activity',
|
|
COMMANDSPAN : 'span.commands',
|
|
SPINNERCOMMANDSPAN : 'span.commands',
|
|
CONTENTAFTERLINK : 'div.contentafterlink',
|
|
DELETE : 'a.editing_delete',
|
|
DIMCLASS : 'dimmed',
|
|
DIMMEDTEXT : 'dimmed_text',
|
|
EDITTITLE : 'a.editing_title',
|
|
EDITTITLECLASS : 'edittitle',
|
|
GENERICICONCLASS : 'iconsmall',
|
|
GROUPSNONE : 'a.editing_groupsnone',
|
|
GROUPSSEPARATE : 'a.editing_groupsseparate',
|
|
GROUPSVISIBLE : 'a.editing_groupsvisible',
|
|
HASLABEL : 'label',
|
|
HIDE : 'a.editing_hide',
|
|
HIGHLIGHT : 'a.editing_highlight',
|
|
INSTANCENAME : 'span.instancename',
|
|
LIGHTBOX : 'lightbox',
|
|
MODINDENTCOUNT : 'mod-indent-',
|
|
MODINDENTDIV : 'div.mod-indent',
|
|
MODINDENTHUGE : 'mod-indent-huge',
|
|
MODULEIDPREFIX : 'module-',
|
|
MOVELEFT : 'a.editing_moveleft',
|
|
MOVELEFTCLASS : 'editing_moveleft',
|
|
MOVERIGHT : 'a.editing_moveright',
|
|
PAGECONTENT : 'div#page-content',
|
|
RIGHTSIDE : '.right',
|
|
SECTIONHIDDENCLASS : 'hidden',
|
|
SECTIONIDPREFIX : 'section-',
|
|
SECTIONLI : 'li.section',
|
|
SHOW : 'a.editing_show',
|
|
SHOWHIDE : 'a.editing_showhide',
|
|
CONDITIONALHIDDEN : 'conditionalhidden',
|
|
AVAILABILITYINFODIV : 'div.availabilityinfo',
|
|
SHOWCLASS : 'editing_show',
|
|
ACCESSHIDECLASS : 'accesshide'
|
|
};
|
|
|
|
/**
|
|
* The toolbox classes
|
|
*
|
|
* TOOLBOX is a generic class which should never be directly instantiated
|
|
* RESOURCETOOLBOX is a class extending TOOLBOX containing code specific to resources
|
|
* SECTIONTOOLBOX is a class extending TOOLBOX containing code specific to sections
|
|
*/
|
|
var TOOLBOX = function() {
|
|
TOOLBOX.superclass.constructor.apply(this, arguments);
|
|
}
|
|
|
|
Y.extend(TOOLBOX, Y.Base, {
|
|
/**
|
|
* Toggle the visibility and availability for the specified
|
|
* resource show/hide button
|
|
*/
|
|
toggle_hide_resource_ui : function(button) {
|
|
var element = button.ancestor(CSS.ACTIVITYLI);
|
|
var hideicon = button.one('img');
|
|
|
|
var dimarea;
|
|
var toggle_class;
|
|
if (this.is_label(element)) {
|
|
toggle_class = CSS.DIMMEDTEXT;
|
|
dimarea = element.one(CSS.MODINDENTDIV + ' div');
|
|
} else {
|
|
toggle_class = CSS.DIMCLASS;
|
|
dimarea = element.one('a');
|
|
}
|
|
|
|
var status = '';
|
|
var value;
|
|
if (button.hasClass(CSS.SHOWCLASS)) {
|
|
status = 'hide';
|
|
value = 1;
|
|
} else {
|
|
status = 'show';
|
|
value = 0;
|
|
}
|
|
// Update button info.
|
|
var newstring = M.util.get_string(status, 'moodle');
|
|
hideicon.setAttrs({
|
|
'alt' : newstring,
|
|
'src' : M.util.image_url('t/' + status)
|
|
});
|
|
button.set('title', newstring);
|
|
button.set('className', 'editing_'+status);
|
|
|
|
// If activity is conditionally hidden, then don't toggle.
|
|
if (!dimarea.hasClass(CSS.CONDITIONALHIDDEN)) {
|
|
// Change the UI.
|
|
dimarea.toggleClass(toggle_class);
|
|
// We need to toggle dimming on the description too.
|
|
element.all(CSS.CONTENTAFTERLINK).toggleClass(CSS.DIMMEDTEXT);
|
|
}
|
|
// Toggle availablity info for conditional activities.
|
|
var availabilityinfo = element.one(CSS.AVAILABILITYINFODIV);
|
|
|
|
if (availabilityinfo) {
|
|
availabilityinfo.toggleClass(CSS.ACCESSHIDECLASS);
|
|
}
|
|
return value;
|
|
},
|
|
/**
|
|
* Send a request using the REST API
|
|
*
|
|
* @param data The data to submit
|
|
* @param statusspinner (optional) A statusspinner which may contain a section loader
|
|
* @param optionalconfig (optional) Any additional configuration to submit
|
|
* @return response responseText field from responce
|
|
*/
|
|
send_request : function(data, statusspinner, optionalconfig) {
|
|
// Default data structure
|
|
if (!data) {
|
|
data = {};
|
|
}
|
|
// Handle any variables which we must pass back through to
|
|
var pageparams = this.get('config').pageparams;
|
|
for (varname in pageparams) {
|
|
data[varname] = pageparams[varname];
|
|
}
|
|
|
|
data.sesskey = M.cfg.sesskey;
|
|
data.courseId = this.get('courseid');
|
|
|
|
var uri = M.cfg.wwwroot + this.get('ajaxurl');
|
|
|
|
// Define the configuration to send with the request
|
|
var responsetext = [];
|
|
var config = {
|
|
method: 'POST',
|
|
data: data,
|
|
on: {
|
|
success: function(tid, response) {
|
|
try {
|
|
responsetext = Y.JSON.parse(response.responseText);
|
|
if (responsetext.error) {
|
|
new M.core.ajaxException(responsetext);
|
|
}
|
|
} catch (e) {}
|
|
if (statusspinner) {
|
|
window.setTimeout(function(e) {
|
|
statusspinner.hide();
|
|
}, 400);
|
|
}
|
|
},
|
|
failure : function(tid, response) {
|
|
if (statusspinner) {
|
|
statusspinner.hide();
|
|
}
|
|
new M.core.ajaxException(response);
|
|
}
|
|
},
|
|
context: this,
|
|
sync: true
|
|
}
|
|
|
|
// Apply optional config
|
|
if (optionalconfig) {
|
|
for (varname in optionalconfig) {
|
|
config[varname] = optionalconfig[varname];
|
|
}
|
|
}
|
|
|
|
if (statusspinner) {
|
|
statusspinner.show();
|
|
}
|
|
|
|
// Send the request
|
|
Y.io(uri, config);
|
|
return responsetext;
|
|
},
|
|
is_label : function(target) {
|
|
return target.hasClass(CSS.HASLABEL);
|
|
},
|
|
/**
|
|
* Return the module ID for the specified element
|
|
*
|
|
* @param element The <li> element to determine a module-id number for
|
|
* @return string The module ID
|
|
*/
|
|
get_element_id : function(element) {
|
|
return element.get('id').replace(CSS.MODULEIDPREFIX, '');
|
|
},
|
|
/**
|
|
* Return the module ID for the specified element
|
|
*
|
|
* @param element The <li> element to determine a module-id number for
|
|
* @return string The module ID
|
|
*/
|
|
get_section_id : function(section) {
|
|
return section.get('id').replace(CSS.SECTIONIDPREFIX, '');
|
|
}
|
|
},
|
|
{
|
|
NAME : 'course-toolbox',
|
|
ATTRS : {
|
|
// The ID of the current course
|
|
courseid : {
|
|
'value' : 0
|
|
},
|
|
ajaxurl : {
|
|
'value' : 0
|
|
},
|
|
config : {
|
|
'value' : 0
|
|
}
|
|
}
|
|
}
|
|
);
|
|
|
|
|
|
var RESOURCETOOLBOX = function() {
|
|
RESOURCETOOLBOX.superclass.constructor.apply(this, arguments);
|
|
}
|
|
|
|
Y.extend(RESOURCETOOLBOX, TOOLBOX, {
|
|
// Variables
|
|
GROUPS_NONE : 0,
|
|
GROUPS_SEPARATE : 1,
|
|
GROUPS_VISIBLE : 2,
|
|
|
|
/**
|
|
* Initialize the resource toolbox
|
|
*
|
|
* Updates all span.commands with relevant handlers and other required changes
|
|
*/
|
|
initializer : function(config) {
|
|
this.setup_for_resource();
|
|
M.course.coursebase.register_module(this);
|
|
|
|
var prefix = CSS.ACTIVITYLI + ' ' + CSS.COMMANDSPAN + ' ';
|
|
Y.delegate('click', this.edit_resource_title, CSS.PAGECONTENT, prefix + CSS.EDITTITLE, this);
|
|
Y.delegate('click', this.move_left, CSS.PAGECONTENT, prefix + CSS.MOVELEFT, this);
|
|
Y.delegate('click', this.move_right, CSS.PAGECONTENT, prefix + CSS.MOVERIGHT, this);
|
|
Y.delegate('click', this.delete_resource, CSS.PAGECONTENT, prefix + CSS.DELETE, this);
|
|
Y.delegate('click', this.toggle_hide_resource, CSS.PAGECONTENT, prefix + CSS.HIDE, this);
|
|
Y.delegate('click', this.toggle_hide_resource, CSS.PAGECONTENT, prefix + CSS.SHOW, this);
|
|
Y.delegate('click', this.toggle_groupmode, CSS.PAGECONTENT, prefix + CSS.GROUPSNONE, this);
|
|
Y.delegate('click', this.toggle_groupmode, CSS.PAGECONTENT, prefix + CSS.GROUPSSEPARATE, this);
|
|
Y.delegate('click', this.toggle_groupmode, CSS.PAGECONTENT, prefix + CSS.GROUPSVISIBLE, this);
|
|
},
|
|
|
|
/**
|
|
* Update any span.commands within the scope of the specified
|
|
* selector with AJAX equivelants
|
|
*
|
|
* @param baseselector The selector to limit scope to
|
|
* @return void
|
|
*/
|
|
setup_for_resource : function(baseselector) {
|
|
if (!baseselector) {
|
|
var baseselector = CSS.PAGECONTENT + ' ' + CSS.ACTIVITYLI;
|
|
}
|
|
|
|
Y.all(baseselector).each(this._setup_for_resource, this);
|
|
},
|
|
_setup_for_resource : function(toolboxtarget) {
|
|
toolboxtarget = Y.one(toolboxtarget);
|
|
// "Disable" show/hide icons (change cursor to not look clickable) if section is hidden
|
|
var showhide = toolboxtarget.all(CSS.COMMANDSPAN + ' ' + CSS.HIDE);
|
|
showhide.concat(toolboxtarget.all(CSS.COMMANDSPAN + ' ' + CSS.SHOW));
|
|
showhide.each(function(node) {
|
|
var section = node.ancestor(CSS.SECTIONLI);
|
|
if (section && section.hasClass(CSS.SECTIONHIDDENCLASS)) {
|
|
node.setStyle('cursor', 'auto');
|
|
}
|
|
});
|
|
|
|
// Set groupmode attribute for use by this.toggle_groupmode()
|
|
var groups;
|
|
groups = toolboxtarget.all(CSS.COMMANDSPAN + ' ' + CSS.GROUPSNONE);
|
|
groups.setAttribute('groupmode', this.GROUPS_NONE);
|
|
|
|
groups = toolboxtarget.all(CSS.COMMANDSPAN + ' ' + CSS.GROUPSSEPARATE);
|
|
groups.setAttribute('groupmode', this.GROUPS_SEPARATE);
|
|
|
|
groups = toolboxtarget.all(CSS.COMMANDSPAN + ' ' + CSS.GROUPSVISIBLE);
|
|
groups.setAttribute('groupmode', this.GROUPS_VISIBLE);
|
|
},
|
|
move_left : function(e) {
|
|
this.move_leftright(e, -1);
|
|
},
|
|
move_right : function(e) {
|
|
this.move_leftright(e, 1);
|
|
},
|
|
move_leftright : function(e, direction) {
|
|
// Prevent the default button action
|
|
e.preventDefault();
|
|
|
|
// Get the element we're working on
|
|
var element = e.target.ancestor(CSS.ACTIVITYLI);
|
|
|
|
// And we need to determine the current and new indent level
|
|
var indentdiv = element.one(CSS.MODINDENTDIV);
|
|
var indent = indentdiv.getAttribute('class').match(/mod-indent-(\d{1,})/);
|
|
|
|
if (indent) {
|
|
var oldindent = parseInt(indent[1]);
|
|
var newindent = Math.max(0, (oldindent + parseInt(direction)));
|
|
indentdiv.removeClass(indent[0]);
|
|
} else {
|
|
var oldindent = 0;
|
|
var newindent = 1;
|
|
}
|
|
|
|
// Perform the move
|
|
indentdiv.addClass(CSS.MODINDENTCOUNT + newindent);
|
|
var data = {
|
|
'class' : 'resource',
|
|
'field' : 'indent',
|
|
'value' : newindent,
|
|
'id' : this.get_element_id(element)
|
|
};
|
|
var spinner = M.util.add_spinner(Y, element.one(CSS.SPINNERCOMMANDSPAN));
|
|
this.send_request(data, spinner);
|
|
|
|
// Handle removal/addition of the moveleft button
|
|
if (newindent == 0) {
|
|
element.one(CSS.MOVELEFT).remove();
|
|
} else if (newindent == 1 && oldindent == 0) {
|
|
this.add_moveleft(element);
|
|
}
|
|
|
|
// Handle massive indentation to match non-ajax display
|
|
var hashugeclass = indentdiv.hasClass(CSS.MODINDENTHUGE);
|
|
if (newindent > 15 && !hashugeclass) {
|
|
indentdiv.addClass(CSS.MODINDENTHUGE);
|
|
} else if (newindent <= 15 && hashugeclass) {
|
|
indentdiv.removeClass(CSS.MODINDENTHUGE);
|
|
}
|
|
},
|
|
delete_resource : function(e) {
|
|
// Prevent the default button action
|
|
e.preventDefault();
|
|
|
|
// Get the element we're working on
|
|
var element = e.target.ancestor(CSS.ACTIVITYLI);
|
|
|
|
var confirmstring = '';
|
|
if (this.is_label(element)) {
|
|
// Labels are slightly different to other activities
|
|
var plugindata = {
|
|
type : M.util.get_string('pluginname', 'label')
|
|
}
|
|
confirmstring = M.util.get_string('deletechecktype', 'moodle', plugindata)
|
|
} else {
|
|
var plugindata = {
|
|
type : M.util.get_string('pluginname', element.getAttribute('class').match(/modtype_([^\s]*)/)[1]),
|
|
name : element.one(CSS.INSTANCENAME).get('firstChild').get('data')
|
|
}
|
|
confirmstring = M.util.get_string('deletechecktypename', 'moodle', plugindata);
|
|
}
|
|
|
|
// Confirm element removal
|
|
if (!confirm(confirmstring)) {
|
|
return false;
|
|
}
|
|
|
|
// Actually remove the element
|
|
element.remove();
|
|
var data = {
|
|
'class' : 'resource',
|
|
'action' : 'DELETE',
|
|
'id' : this.get_element_id(element)
|
|
};
|
|
this.send_request(data);
|
|
},
|
|
toggle_hide_resource : function(e) {
|
|
// Prevent the default button action
|
|
e.preventDefault();
|
|
|
|
// Return early if the current section is hidden
|
|
var section = e.target.ancestor(M.course.format.get_section_selector(Y));
|
|
if (section && section.hasClass(CSS.SECTIONHIDDENCLASS)) {
|
|
return;
|
|
}
|
|
|
|
// Get the element we're working on
|
|
var element = e.target.ancestor(CSS.ACTIVITYLI);
|
|
|
|
var button = e.target.ancestor('a', true);
|
|
|
|
var value = this.toggle_hide_resource_ui(button);
|
|
|
|
// Send the request
|
|
var data = {
|
|
'class' : 'resource',
|
|
'field' : 'visible',
|
|
'value' : value,
|
|
'id' : this.get_element_id(element)
|
|
};
|
|
var spinner = M.util.add_spinner(Y, element.one(CSS.SPINNERCOMMANDSPAN));
|
|
this.send_request(data, spinner);
|
|
return false; // Need to return false to stop the delegate for the new state firing
|
|
},
|
|
toggle_groupmode : function(e) {
|
|
// Prevent the default button action
|
|
e.preventDefault();
|
|
|
|
// Get the element we're working on
|
|
var element = e.target.ancestor(CSS.ACTIVITYLI);
|
|
|
|
var button = e.target.ancestor('a', true);
|
|
var icon = button.one('img');
|
|
|
|
// Current Mode
|
|
var groupmode = button.getAttribute('groupmode');
|
|
groupmode++;
|
|
if (groupmode > 2) {
|
|
groupmode = 0;
|
|
}
|
|
button.setAttribute('groupmode', groupmode);
|
|
|
|
var newtitle = '';
|
|
var iconsrc = '';
|
|
switch (groupmode) {
|
|
case this.GROUPS_NONE:
|
|
newtitle = 'groupsnone';
|
|
iconsrc = M.util.image_url('t/groupn');
|
|
break;
|
|
case this.GROUPS_SEPARATE:
|
|
newtitle = 'groupsseparate';
|
|
iconsrc = M.util.image_url('t/groups');
|
|
break;
|
|
case this.GROUPS_VISIBLE:
|
|
newtitle = 'groupsvisible';
|
|
iconsrc = M.util.image_url('t/groupv');
|
|
break;
|
|
}
|
|
newtitle = M.util.get_string('clicktochangeinbrackets', 'moodle',
|
|
M.util.get_string(newtitle, 'moodle'));
|
|
|
|
// Change the UI
|
|
icon.setAttrs({
|
|
'alt' : newtitle,
|
|
'src' : iconsrc
|
|
});
|
|
button.setAttribute('title', newtitle);
|
|
|
|
// And send the request
|
|
var data = {
|
|
'class' : 'resource',
|
|
'field' : 'groupmode',
|
|
'value' : groupmode,
|
|
'id' : this.get_element_id(element)
|
|
};
|
|
var spinner = M.util.add_spinner(Y, element.one(CSS.SPINNERCOMMANDSPAN));
|
|
this.send_request(data, spinner);
|
|
return false; // Need to return false to stop the delegate for the new state firing
|
|
},
|
|
/**
|
|
* Add the moveleft button
|
|
* This is required after moving left from an initial position of 0
|
|
*
|
|
* @param target The encapsulating <li> element
|
|
*/
|
|
add_moveleft : function(target) {
|
|
var left_string = M.util.get_string('moveleft', 'moodle');
|
|
var moveimage = 't/left'; // ltr mode
|
|
if ( Y.one(document.body).hasClass('dir-rtl') ) {
|
|
moveimage = 't/right';
|
|
} else {
|
|
moveimage = 't/left';
|
|
}
|
|
var newicon = Y.Node.create('<img />')
|
|
.addClass(CSS.GENERICICONCLASS)
|
|
.setAttrs({
|
|
'src' : M.util.image_url(moveimage, 'moodle'),
|
|
'alt' : left_string
|
|
});
|
|
var moveright = target.one(CSS.MOVERIGHT);
|
|
var newlink = moveright.getAttribute('href').replace('indent=1', 'indent=-1');
|
|
var anchor = new Y.Node.create('<a />')
|
|
.setStyle('cursor', 'pointer')
|
|
.addClass(CSS.MOVELEFTCLASS)
|
|
.setAttribute('href', newlink)
|
|
.setAttribute('title', left_string);
|
|
anchor.appendChild(newicon);
|
|
anchor.on('click', this.move_left, this);
|
|
moveright.insert(anchor, 'before');
|
|
},
|
|
/**
|
|
* Edit the title for the resource
|
|
*/
|
|
edit_resource_title : function(e) {
|
|
// Get the element we're working on
|
|
var element = e.target.ancestor(CSS.ACTIVITYLI);
|
|
var instancename = element.one(CSS.INSTANCENAME);
|
|
var currenttitle = instancename.get('firstChild');
|
|
var oldtitle = currenttitle.get('data');
|
|
var titletext = oldtitle;
|
|
var editbutton = element.one('a.' + CSS.EDITTITLECLASS + ' img');
|
|
|
|
// Handle events for edit_resource_title
|
|
var listenevents = [];
|
|
var thisevent;
|
|
|
|
// Grab the anchor so that we can swap it with the edit form
|
|
var anchor = instancename.ancestor('a');
|
|
|
|
var data = {
|
|
'class' : 'resource',
|
|
'field' : 'gettitle',
|
|
'id' : this.get_element_id(element)
|
|
};
|
|
|
|
// Try to retrieve the existing string from the server
|
|
var response = this.send_request(data, editbutton);
|
|
if (response.instancename) {
|
|
titletext = response.instancename;
|
|
}
|
|
|
|
// Create the editor and submit button
|
|
var editor = Y.Node.create('<input />')
|
|
.setAttrs({
|
|
'name' : 'title',
|
|
'value' : titletext,
|
|
'autocomplete' : 'off'
|
|
})
|
|
.addClass('titleeditor');
|
|
var editform = Y.Node.create('<form />')
|
|
.setStyle('padding', '0')
|
|
.setStyle('display', 'inline')
|
|
.setAttribute('action', '#');
|
|
|
|
var editinstructions = Y.Node.create('<span />')
|
|
.addClass('editinstructions')
|
|
.set('innerHTML', M.util.get_string('edittitleinstructions', 'moodle'));
|
|
|
|
// Clear the existing content and put the editor in
|
|
currenttitle.set('data', '');
|
|
editform.appendChild(editor);
|
|
anchor.replace(editform);
|
|
element.appendChild(editinstructions);
|
|
e.preventDefault();
|
|
|
|
// Focus and select the editor text
|
|
editor.focus().select();
|
|
|
|
// Handle removal of the editor
|
|
var clear_edittitle = function() {
|
|
// Detach all listen events to prevent duplicate triggers
|
|
var thisevent;
|
|
while (thisevent = listenevents.shift()) {
|
|
thisevent.detach();
|
|
}
|
|
|
|
if (editinstructions) {
|
|
// Convert back to anchor and remove instructions
|
|
editform.replace(anchor);
|
|
editinstructions.remove();
|
|
editinstructions = null;
|
|
}
|
|
}
|
|
|
|
// Handle cancellation of the editor
|
|
var cancel_edittitle = function(e) {
|
|
clear_edittitle();
|
|
|
|
// Set the title and anchor back to their previous settings
|
|
currenttitle.set('data', oldtitle);
|
|
};
|
|
|
|
// Cancel the edit if we lose focus or the escape key is pressed
|
|
thisevent = editor.on('blur', cancel_edittitle);
|
|
listenevents.push(thisevent);
|
|
thisevent = Y.one('document').on('keyup', function(e) {
|
|
if (e.keyCode == 27) {
|
|
cancel_edittitle(e);
|
|
}
|
|
});
|
|
listenevents.push(thisevent);
|
|
|
|
// Handle form submission
|
|
thisevent = editform.on('submit', function(e) {
|
|
// We don't actually want to submit anything
|
|
e.preventDefault();
|
|
|
|
// Clear the edit title boxes
|
|
clear_edittitle();
|
|
|
|
// We only accept strings which have valid content
|
|
var newtitle = Y.Lang.trim(editor.get('value'));
|
|
if (newtitle != null && newtitle != "" && newtitle != titletext) {
|
|
var data = {
|
|
'class' : 'resource',
|
|
'field' : 'updatetitle',
|
|
'title' : newtitle,
|
|
'id' : this.get_element_id(element)
|
|
};
|
|
var response = this.send_request(data, editbutton);
|
|
if (response.instancename) {
|
|
currenttitle.set('data', response.instancename);
|
|
}
|
|
} else {
|
|
// Invalid content. Set the title back to it's original contents
|
|
currenttitle.set('data', oldtitle);
|
|
}
|
|
}, this);
|
|
listenevents.push(thisevent);
|
|
}
|
|
}, {
|
|
NAME : 'course-resource-toolbox',
|
|
ATTRS : {
|
|
courseid : {
|
|
'value' : 0
|
|
},
|
|
format : {
|
|
'value' : 'topics'
|
|
}
|
|
}
|
|
});
|
|
|
|
var SECTIONTOOLBOX = function() {
|
|
SECTIONTOOLBOX.superclass.constructor.apply(this, arguments);
|
|
}
|
|
|
|
Y.extend(SECTIONTOOLBOX, TOOLBOX, {
|
|
/**
|
|
* Initialize the toolboxes module
|
|
*
|
|
* Updates all span.commands with relevant handlers and other required changes
|
|
*/
|
|
initializer : function(config) {
|
|
this.setup_for_section();
|
|
M.course.coursebase.register_module(this);
|
|
|
|
// Section Highlighting
|
|
Y.delegate('click', this.toggle_highlight, CSS.PAGECONTENT, CSS.SECTIONLI + ' ' + CSS.HIGHLIGHT, this);
|
|
// Section Visibility
|
|
Y.delegate('click', this.toggle_hide_section, CSS.PAGECONTENT, CSS.SECTIONLI + ' ' + CSS.SHOWHIDE, this);
|
|
},
|
|
/**
|
|
* Update any section areas within the scope of the specified
|
|
* selector with AJAX equivelants
|
|
*
|
|
* @param baseselector The selector to limit scope to
|
|
* @return void
|
|
*/
|
|
setup_for_section : function(baseselector) {
|
|
// Left here for potential future use - not currently needed due to YUI delegation in initializer()
|
|
/*if (!baseselector) {
|
|
var baseselector = CSS.PAGECONTENT;
|
|
}
|
|
|
|
Y.all(baseselector).each(this._setup_for_section, this);*/
|
|
},
|
|
_setup_for_section : function(toolboxtarget) {
|
|
// Left here for potential future use - not currently needed due to YUI delegation in initializer()
|
|
},
|
|
toggle_hide_section : function(e) {
|
|
// Prevent the default button action
|
|
e.preventDefault();
|
|
|
|
// Get the section we're working on
|
|
var section = e.target.ancestor(M.course.format.get_section_selector(Y));
|
|
var button = e.target.ancestor('a', true);
|
|
var hideicon = button.one('img');
|
|
|
|
// The value to submit
|
|
var value;
|
|
// The status text for strings and images
|
|
var status;
|
|
|
|
if (!section.hasClass(CSS.SECTIONHIDDENCLASS)) {
|
|
section.addClass(CSS.SECTIONHIDDENCLASS);
|
|
value = 0;
|
|
status = 'show';
|
|
|
|
} else {
|
|
section.removeClass(CSS.SECTIONHIDDENCLASS);
|
|
value = 1;
|
|
status = 'hide';
|
|
}
|
|
|
|
var newstring = M.util.get_string(status + 'fromothers', 'format_' + this.get('format'));
|
|
hideicon.setAttrs({
|
|
'alt' : newstring,
|
|
'src' : M.util.image_url('i/' + status)
|
|
});
|
|
button.set('title', newstring);
|
|
|
|
// Change the highlight status
|
|
var data = {
|
|
'class' : 'section',
|
|
'field' : 'visible',
|
|
'id' : this.get_section_id(section.ancestor(M.course.format.get_section_wrapper(Y), true)),
|
|
'value' : value
|
|
};
|
|
|
|
var lightbox = M.util.add_lightbox(Y, section);
|
|
lightbox.show();
|
|
|
|
var response = this.send_request(data, lightbox);
|
|
|
|
var activities = section.all(CSS.ACTIVITYLI);
|
|
activities.each(function(node) {
|
|
if (node.one(CSS.SHOW)) {
|
|
var button = node.one(CSS.SHOW);
|
|
} else {
|
|
var button = node.one(CSS.HIDE);
|
|
}
|
|
var activityid = this.get_element_id(node);
|
|
|
|
if (Y.Array.indexOf(response.resourcestotoggle, activityid) != -1) {
|
|
this.toggle_hide_resource_ui(button);
|
|
}
|
|
|
|
if (value == 0) {
|
|
button.setStyle('cursor', 'auto');
|
|
} else {
|
|
button.setStyle('cursor', 'pointer');
|
|
}
|
|
}, this);
|
|
},
|
|
toggle_highlight : function(e) {
|
|
// Prevent the default button action
|
|
e.preventDefault();
|
|
|
|
// Get the section we're working on
|
|
var section = e.target.ancestor(M.course.format.get_section_selector(Y));
|
|
var button = e.target.ancestor('a', true);
|
|
var buttonicon = button.one('img');
|
|
|
|
// Determine whether the marker is currently set
|
|
var togglestatus = section.hasClass('current');
|
|
var value = 0;
|
|
|
|
// Set the current highlighted item text
|
|
var old_string = M.util.get_string('markthistopic', 'moodle');
|
|
Y.one(CSS.PAGECONTENT)
|
|
.all(M.course.format.get_section_selector(Y) + '.current ' + CSS.HIGHLIGHT)
|
|
.set('title', old_string);
|
|
Y.one(CSS.PAGECONTENT)
|
|
.all(M.course.format.get_section_selector(Y) + '.current ' + CSS.HIGHLIGHT + ' img')
|
|
.set('alt', old_string)
|
|
.set('src', M.util.image_url('i/marker'));
|
|
|
|
// Remove the highlighting from all sections
|
|
var allsections = Y.one(CSS.PAGECONTENT).all(M.course.format.get_section_selector(Y))
|
|
.removeClass('current');
|
|
|
|
// Then add it if required to the selected section
|
|
if (!togglestatus) {
|
|
section.addClass('current');
|
|
value = this.get_section_id(section.ancestor(M.course.format.get_section_wrapper(Y), true));
|
|
var new_string = M.util.get_string('markedthistopic', 'moodle');
|
|
button
|
|
.set('title', new_string);
|
|
buttonicon
|
|
.set('alt', new_string)
|
|
.set('src', M.util.image_url('i/marked'));
|
|
}
|
|
|
|
// Change the highlight status
|
|
var data = {
|
|
'class' : 'course',
|
|
'field' : 'marker',
|
|
'value' : value
|
|
};
|
|
var lightbox = M.util.add_lightbox(Y, section);
|
|
lightbox.show();
|
|
this.send_request(data, lightbox);
|
|
}
|
|
}, {
|
|
NAME : 'course-section-toolbox',
|
|
ATTRS : {
|
|
courseid : {
|
|
'value' : 0
|
|
},
|
|
format : {
|
|
'value' : 'topics'
|
|
}
|
|
}
|
|
});
|
|
|
|
M.course = M.course || {};
|
|
|
|
M.course.init_resource_toolbox = function(config) {
|
|
return new RESOURCETOOLBOX(config);
|
|
};
|
|
|
|
M.course.init_section_toolbox = function(config) {
|
|
return new SECTIONTOOLBOX(config);
|
|
};
|
|
|
|
},
|
|
'@VERSION@', {
|
|
requires : ['base', 'node', 'io', 'moodle-course-coursebase']
|
|
}
|
|
);
|