'no-unreachable': 'warn',
'no-unsafe-finally': 'error',
'use-isnan': 'error',
- 'valid-jsdoc': ['warn', { 'requireReturn': false }],
+ 'valid-jsdoc': ['warn', { 'requireReturn': false, 'requireParamDescription': false, 'requireReturnDescription': false }],
'valid-typeof': 'error',
// === Best Practices ===
'max-params': 'off',
'max-statements': 'off',
'max-statements-per-line': 'off',
- 'new-cap': 'warn',
+ 'new-cap': ['warn', { 'properties': false }],
'new-parens': 'warn',
'newline-after-var': 'off',
'newline-before-return': 'off',
get_string('requiremodintro', 'admin'), get_string('requiremodintro_desc', 'admin'), 0));
$ADMIN->add('modsettings', $temp);
- foreach (core_plugin_manager::instance()->get_plugins_of_type('mod') as $plugin) {
+ $plugins = core_plugin_manager::instance()->get_plugins_of_type('mod');
+ core_collator::asort_objects_by_property($plugins, 'displayname');
+ foreach ($plugins as $plugin) {
/** @var \core\plugininfo\mod $plugin */
$plugin->load_settings($ADMIN, 'modsettings', $hassiteconfig);
}
$temp = new admin_settingpage('manageformats', new lang_string('manageformats', 'core_admin'));
$temp->add(new admin_setting_manageformats());
$ADMIN->add('formatsettings', $temp);
- foreach (core_plugin_manager::instance()->get_plugins_of_type('format') as $plugin) {
+ $plugins = core_plugin_manager::instance()->get_plugins_of_type('format');
+ core_collator::asort_objects_by_property($plugins, 'displayname');
+ foreach ($plugins as $plugin) {
/** @var \core\plugininfo\format $plugin */
$plugin->load_settings($ADMIN, 'formatsettings', $hassiteconfig);
}
// blocks
$ADMIN->add('modules', new admin_category('blocksettings', new lang_string('blocks')));
$ADMIN->add('blocksettings', new admin_page_manageblocks());
- foreach (core_plugin_manager::instance()->get_plugins_of_type('block') as $plugin) {
+ $plugins = core_plugin_manager::instance()->get_plugins_of_type('block');
+ core_collator::asort_objects_by_property($plugins, 'displayname');
+ foreach ($plugins as $plugin) {
/** @var \core\plugininfo\block $plugin */
$plugin->load_settings($ADMIN, 'blocksettings', $hassiteconfig);
}
$ADMIN->add('modules', new admin_category('messageoutputs', new lang_string('messageoutputs', 'message')));
$ADMIN->add('messageoutputs', new admin_page_managemessageoutputs());
$ADMIN->add('messageoutputs', new admin_page_defaultmessageoutputs());
- foreach (core_plugin_manager::instance()->get_plugins_of_type('message') as $plugin) {
+ $plugins = core_plugin_manager::instance()->get_plugins_of_type('message');
+ core_collator::asort_objects_by_property($plugins, 'displayname');
+ foreach ($plugins as $plugin) {
/** @var \core\plugininfo\message $plugin */
$plugin->load_settings($ADMIN, 'messageoutputs', $hassiteconfig);
}
$temp = new admin_externalpage('authtestsettings', get_string('testsettings', 'core_auth'), new moodle_url("/auth/test_settings.php"), 'moodle/site:config', true);
$ADMIN->add('authsettings', $temp);
- foreach (core_plugin_manager::instance()->get_plugins_of_type('auth') as $plugin) {
+ $plugins = core_plugin_manager::instance()->get_plugins_of_type('auth');
+ core_collator::asort_objects_by_property($plugins, 'displayname');
+ foreach ($plugins as $plugin) {
/** @var \core\plugininfo\auth $plugin */
$plugin->load_settings($ADMIN, 'authsettings', $hassiteconfig);
}
$temp = new admin_externalpage('enroltestsettings', get_string('testsettings', 'core_enrol'), new moodle_url("/enrol/test_settings.php"), 'moodle/site:config', true);
$ADMIN->add('enrolments', $temp);
- foreach(core_plugin_manager::instance()->get_plugins_of_type('enrol') as $plugin) {
+ $plugins = core_plugin_manager::instance()->get_plugins_of_type('enrol');
+ core_collator::asort_objects_by_property($plugins, 'displayname');
+ foreach ($plugins as $plugin) {
/** @var \core\plugininfo\enrol $plugin */
$plugin->load_settings($ADMIN, 'enrolments', $hassiteconfig);
}
$temp = new admin_settingpage('manageeditors', new lang_string('editorsettings', 'editor'));
$temp->add(new admin_setting_manageeditors());
$ADMIN->add('editorsettings', $temp);
- foreach (core_plugin_manager::instance()->get_plugins_of_type('editor') as $plugin) {
+ $plugins = core_plugin_manager::instance()->get_plugins_of_type('editor');
+ core_collator::asort_objects_by_property($plugins, 'displayname');
+ foreach ($plugins as $plugin) {
/** @var \core\plugininfo\editor $plugin */
$plugin->load_settings($ADMIN, 'editorsettings', $hassiteconfig);
}
$temp = new admin_settingpage('manageantiviruses', new lang_string('antivirussettings', 'antivirus'));
$temp->add(new admin_setting_manageantiviruses());
$ADMIN->add('antivirussettings', $temp);
- foreach (core_plugin_manager::instance()->get_plugins_of_type('antivirus') as $plugin) {
+ $plugins = core_plugin_manager::instance()->get_plugins_of_type('antivirus');
+ core_collator::asort_objects_by_property($plugins, 'displayname');
+ foreach ($plugins as $plugin) {
/* @var \core\plugininfo\antivirus $plugin */
$plugin->load_settings($ADMIN, 'antivirussettings', $hassiteconfig);
}
}
$ADMIN->add('filtersettings', $temp);
- foreach (core_plugin_manager::instance()->get_plugins_of_type('filter') as $plugin) {
+ $plugins = core_plugin_manager::instance()->get_plugins_of_type('filter');
+ core_collator::asort_objects_by_property($plugins, 'displayname');
+ foreach ($plugins as $plugin) {
/** @var \core\plugininfo\filter $plugin */
$plugin->load_settings($ADMIN, 'filtersettings', $hassiteconfig);
}
new lang_string('createrepository', 'repository'), $url, 'moodle/site:config', true));
$ADMIN->add('repositorysettings', new admin_externalpage('repositoryinstanceedit',
new lang_string('editrepositoryinstance', 'repository'), $url, 'moodle/site:config', true));
- foreach (core_plugin_manager::instance()->get_plugins_of_type('repository') as $plugin) {
+ $plugins = core_plugin_manager::instance()->get_plugins_of_type('repository');
+ core_collator::asort_objects_by_property($plugins, 'displayname');
+ foreach ($plugins as $plugin) {
/** @var \core\plugininfo\repository $plugin */
$plugin->load_settings($ADMIN, 'repositorysettings', $hassiteconfig);
}
'admin'), new lang_string('configenablewsdocumentation', 'admin', $wsdoclink), false));
$ADMIN->add('webservicesettings', $temp);
/// links to protocol pages
- foreach (core_plugin_manager::instance()->get_plugins_of_type('webservice') as $plugin) {
+ $plugins = core_plugin_manager::instance()->get_plugins_of_type('webservice');
+ core_collator::asort_objects_by_property($plugins, 'displayname');
+ foreach ($plugins as $plugin) {
/** @var \core\plugininfo\webservice $plugin */
$plugin->load_settings($ADMIN, 'webservicesettings', $hassiteconfig);
}
get_string('responsehistory', 'question'), '', 0, $hiddenofvisible));
// Settings for particular question types.
- foreach (core_plugin_manager::instance()->get_plugins_of_type('qtype') as $plugin) {
+ $plugins = core_plugin_manager::instance()->get_plugins_of_type('qtype');
+ core_collator::asort_objects_by_property($plugins, 'displayname');
+ foreach ($plugins as $plugin) {
/** @var \core\plugininfo\qtype $plugin */
$plugin->load_settings($ADMIN, 'qtypesettings', $hassiteconfig);
}
$ADMIN->add('plagiarism', new admin_externalpage('manageplagiarismplugins', new lang_string('manageplagiarism', 'plagiarism'),
$CFG->wwwroot . '/' . $CFG->admin . '/plagiarism.php'));
- foreach (core_plugin_manager::instance()->get_plugins_of_type('plagiarism') as $plugin) {
+ $plugins = core_plugin_manager::instance()->get_plugins_of_type('plagiarism');
+ core_collator::asort_objects_by_property($plugins, 'displayname');
+ foreach ($plugins as $plugin) {
/** @var \core\plugininfo\plagiarism $plugin */
$plugin->load_settings($ADMIN, 'plagiarism', $hassiteconfig);
}
}
if (!empty($pages)) {
$ADMIN->add('modules', new admin_category('coursereports', new lang_string('coursereports')));
+ core_collator::asort_objects_by_property($pages, 'visiblename');
foreach ($pages as $page) {
$ADMIN->add('coursereports', $page);
}
$ADMIN->add('modules', new admin_category('reportplugins', new lang_string('reports')));
$ADMIN->add('reportplugins', new admin_externalpage('managereports', new lang_string('reportsmanage', 'admin'),
$CFG->wwwroot . '/' . $CFG->admin . '/reports.php'));
+core_collator::asort_objects_by_property($pages, 'visiblename');
foreach ($pages as $page) {
$ADMIN->add('reportplugins', $page);
}
}
$ADMIN->add('searchplugins', $temp);
+ core_collator::asort_objects_by_property($pages, 'visiblename');
foreach ($pages as $page) {
$ADMIN->add('searchplugins', $page);
}
}
// Now add various admin tools.
-foreach (core_plugin_manager::instance()->get_plugins_of_type('tool') as $plugin) {
+$plugins = core_plugin_manager::instance()->get_plugins_of_type('tool');
+core_collator::asort_objects_by_property($plugins, 'displayname');
+foreach ($plugins as $plugin) {
/** @var \core\plugininfo\tool $plugin */
$plugin->load_settings($ADMIN, null, $hassiteconfig);
}
$ADMIN->add('cache', new admin_externalpage('cacheconfig', new lang_string('cacheconfig', 'cache'), $CFG->wwwroot .'/cache/admin.php'));
$ADMIN->add('cache', new admin_externalpage('cachetestperformance', new lang_string('testperformance', 'cache'), $CFG->wwwroot . '/cache/testperformance.php'));
$ADMIN->add('cache', new admin_category('cachestores', new lang_string('cachestores', 'cache')));
+ $ADMIN->locate('cachestores')->set_sorting(true);
foreach (core_component::get_plugin_list('cachestore') as $plugin => $path) {
$settingspath = $path.'/settings.php';
if (file_exists($settingspath)) {
// Add Calendar type settings.
if ($hassiteconfig) {
$ADMIN->add('modules', new admin_category('calendartype', new lang_string('calendartypes', 'calendar')));
- foreach (core_plugin_manager::instance()->get_plugins_of_type('calendartype') as $plugin) {
+ $plugins = core_plugin_manager::instance()->get_plugins_of_type('calendartype');
+ core_collator::asort_objects_by_property($plugins, 'displayname');
+ foreach ($plugins as $plugin) {
/** @var \core\plugininfo\calendartype $plugin */
$plugin->load_settings($ADMIN, 'calendartype', $hassiteconfig);
}
// Extend settings for each local plugin. Note that their settings may be in any part of the
// settings tree and may be visible not only for administrators.
-foreach (core_plugin_manager::instance()->get_plugins_of_type('local') as $plugin) {
+$plugins = core_plugin_manager::instance()->get_plugins_of_type('local');
+core_collator::asort_objects_by_property($plugins, 'displayname');
+foreach ($plugins as $plugin) {
/** @var \core\plugininfo\local $plugin */
$plugin->load_settings($ADMIN, null, $hassiteconfig);
}
if (extension_loaded('pcntl')) {
$disabled = explode(',', ini_get('disable_functions'));
if (!in_array('pcntl_signal', $disabled)) {
+ // Handle interrupts on PHP7.
+ declare(ticks = 1);
+
pcntl_signal(SIGTERM, "signal_handler");
pcntl_signal(SIGINT, "signal_handler");
}
.path-admin-tool-health dl.notice dd {
background-color: #e5db36;
}
-.path-admin-tool-health dt.solution,
-.path-admin-tool-health dd.solution,
+.path-admin-tool-health dl dt.solution,
+.path-admin-tool-health dl dd.solution,
.path-admin-tool-health div#healthnoproblemsfound {
- background-color: #5BB83E !important;
+ background-color: #5BB83E;
}
.path-admin-tool-health dl.healthissues dt,
.path-admin-tool-health dl.healthissues dd {
* Find a node in the dialogue.
*
* @param {String} selector
+ * @return {JQuery} The node
* @method _find
*/
ActionSelector.prototype._find = function(selector) {
for (var i in self._actions) {
choices.push(self._actions[i]);
}
- var content = {'message': self._message, 'choices' : choices,
- 'confirm' : self._confirm, 'cancel' : self._cancel};
+ var content = {'message': self._message, 'choices': choices,
+ 'confirm': self._confirm, 'cancel': self._cancel};
return Templates.render('tool_lp/action_selector', content);
};
*
* @param {Number} itemid
* @param {String} itemtype
+ * @param {Number} pagectxid
*/
var competencies = function(itemid, itemtype, pagectxid) {
this.itemid = itemid;
}
]);
} else {
- return null;
+ return;
}
requests[0].fail(notification.exception);
{ key: message, component: 'tool_lp', param: competency.shortname },
{ key: 'confirm', component: 'moodle' },
{ key: 'cancel', component: 'moodle' }
- ]).done(function (strings) {
+ ]).done(function(strings) {
notification.confirm(
strings[0], // Confirm.
strings[1], // Unlink the competency X from the course?
if (localthis.itemtype == 'course') {
// Course completion rule handling.
- $('[data-region="coursecompetenciespage"]').on('change', 'select[data-field="ruleoutcome"]', function(e){
+ $('[data-region="coursecompetenciespage"]').on('change', 'select[data-field="ruleoutcome"]', function(e) {
var requests = [];
var pagerender = 'tool_lp/course_competencies_page';
var pageregion = 'coursecompetenciespage';
* Get the string for an outcome.
*
* @param {Number} id The outcome code.
- * @return {Promise Resolved with the string.
+ * @return {Promise} Resolved with the string.
* @method getString
*/
getString: function(id) {
/**
* CompetencyPlanNavigation
*
- * @param {String} The selector of the competency element.
- * @param {String} The base url for the page (no params).
- * @param {Number} The user id
- * @param {Number} The competency id
- * @param {Number} The plan id
+ * @param {String} competencySelector The selector of the competency element.
+ * @param {String} baseUrl The base url for the page (no params).
+ * @param {Number} userId The user id
+ * @param {Number} competencyId The competency id
+ * @param {Number} planId The plan id
*/
var CompetencyPlanNavigation = function(competencySelector, baseUrl, userId, competencyId, planId) {
this._baseUrl = baseUrl;
return null;
};
+ // eslint-disable-next-line valid-jsdoc
/**
* Return the type of the module.
*
* Trigger an event.
*
* @param {String} type The type of event.
- * @param {Object} The data to pass to the listeners.
+ * @param {Object} data The data to pass to the listeners.
* @method _trigger
* @protected
*/
var parent = $('[data-region="competencyactions"]').data('competency');
var params = {
- competencyframeworkid : treeModel.getCompetencyFrameworkId(),
+ competencyframeworkid: treeModel.getCompetencyFrameworkId(),
pagecontextid: pageContextId
};
{ key: 'addingcompetencywillresetparentrule', component: 'tool_lp', param: parent.shortname },
{ key: 'yes', component: 'core' },
{ key: 'no', component: 'core' }
- ]).done(function (strings) {
+ ]).done(function(strings) {
notification.confirm(
strings[0],
strings[1],
{ key: confirmMessage, component: 'tool_lp' },
{ key: 'yes', component: 'moodle' },
{ key: 'no', component: 'moodle' }
- ]).done(function (strings) {
+ ]).done(function(strings) {
notification.confirm(
strings[0], // Confirm.
strings[1], // Delete competency X?
});
treeRoot.show();
- body.on('click', '[data-action="move"]', function() { popup.close(); confirmMove(); });
- body.on('click', '[data-action="cancel"]', function() { popup.close(); });
+ body.on('click', '[data-action="move"]', function() {
+ popup.close();
+ confirmMove();
+ });
+ body.on('click', '[data-action="cancel"]', function() {
+ popup.close();
+ });
};
/**
/**
* A node was chosen and "Move" was selected from the menu. Open a popup to select the target.
+ * @param {Event} e
* @method moveHandler
*/
var moveHandler = function(e) {
competencyframeworkid: competency.competencyframeworkid,
searchtext: ''
}
- },{
+ }, {
methodname: 'core_competency_read_competency_framework',
args: {
id: competency.competencyframeworkid
{ key: 'movecompetency', component: 'tool_lp', param: competency.shortname },
{ key: 'move', component: 'tool_lp' },
{ key: 'cancel', component: 'moodle' }
- ]).done(function (strings) {
+ ]).done(function(strings) {
var context = {
framework: framework,
var competency = $('[data-region="competencyactions"]').data('competency');
var params = {
- competencyframeworkid : treeModel.getCompetencyFrameworkId(),
- id : competency.id,
+ competencyframeworkid: treeModel.getCompetencyFrameworkId(),
+ id: competency.id,
parentid: competency.parentid,
pagecontextid: pageContextId
};
/**
* Re-render the page with the latest data.
+ * @param {Object} context
* @method reloadPage
*/
var reloadPage = function(context) {
/**
* Perform a search and render the page with the new search results.
+ * @param {Event} e
* @method updateSearchHandler
*/
var updateSearchHandler = function(e) {
courses: courses
};
templates.render('tool_lp/linked_courses_summary', context).done(function(html) {
- str.get_string('linkedcourses', 'tool_lp').done(function (linkedcourses) {
+ str.get_string('linkedcourses', 'tool_lp').done(function(linkedcourses) {
new Dialogue(
linkedcourses, // Title.
html, // The linked courses.
});
});
- calls.push( {
+ calls.push({
methodname: 'tool_lp_data_for_related_competencies_section',
args: { competencyid: relatedTarget.id }
});
str.get_strings([
{ key: 'competencycannotbedeleted', component: 'tool_lp', param: competency.shortname },
{ key: 'cancel', component: 'moodle' }
- ]).done(function (strings) {
+ ]).done(function(strings) {
notification.alert(
null,
strings[0]
{ key: confirmMessage, component: 'tool_lp', param: competency.shortname },
{ key: 'delete', component: 'moodle' },
{ key: 'cancel', component: 'moodle' }
- ]).done(function (strings) {
+ ]).done(function(strings) {
notification.confirm(
strings[0], // Confirm.
strings[1], // Delete competency X?
/**
* HTML5 implementation of drag/drop (there is an accesible alternative in the menus).
* @method dragStart
+ * @param {Event} e
*/
var dragStart = function(e) {
e.originalEvent.dataTransfer.setData('text', $(e.target).parent().data('id'));
/**
* HTML5 implementation of drag/drop (there is an accesible alternative in the menus).
* @method allowDrop
+ * @param {Event} e
*/
var allowDrop = function(e) {
e.originalEvent.dataTransfer.dropEffect = 'move';
/**
* HTML5 implementation of drag/drop (there is an accesible alternative in the menus).
* @method dragEnter
+ * @param {Event} e
*/
var dragEnter = function(e) {
e.preventDefault();
/**
* HTML5 implementation of drag/drop (there is an accesible alternative in the menus).
* @method dragLeave
+ * @param {Event} e
*/
var dragLeave = function(e) {
e.preventDefault();
/**
* HTML5 implementation of drag/drop (there is an accesible alternative in the menus).
* @method dropOver
+ * @param {Event} e
*/
var dropOver = function(e) {
e.preventDefault();
/**
* Log the competency viewed event.
*
- * @param {Object} The competency.
+ * @param {Object} competency The competency.
* @method triggerCompetencyViewedEvent
*/
var triggerCompetencyViewedEvent = function(competency) {
* @method selectionChanged
* @param {Event} evt The event that triggered the selection change.
* @param {Object} params The parameters for the event. Contains a list of selected nodes.
+ * @return {Boolean}
*/
var selectionChanged = function(evt, params) {
var node = params.selected,
* Return the string "Selected <taxonomy>".
*
* @function parseTaxonomies
- * @param {String} Comma separated list of taxonomies.
+ * @param {String} taxonomiesstr Comma separated list of taxonomies.
* @return {Array} of level => taxonomystr
*/
var parseTaxonomies = function(taxonomiesstr) {
*
*/
var Competencydialogue = function() {
+ // Intentionally left empty.
};
/**
* Log the competency viewed event.
*
- * @param {Number} The competency ID.
+ * @param {Number} competencyId The competency ID.
* @method triggerCompetencyViewedEvent
*/
Competencydialogue.prototype.triggerCompetencyViewedEvent = function(competencyId) {
/**
* The action on the click event.
*
- * @param {Event} event click
+ * @param {Event} e event click
* @method clickEventHandler
*/
Competencydialogue.prototype.clickEventHandler = function(e) {
* Get a promise on data competency.
*
* @param {Number} competencyid
+ * @param {Object} options
* @return {Promise} return promise on data request
* @method getCompetencyDataPromise
*/
* Initialise the competency dialogue module.
*
* Only the first call matters.
- *
- * @return {Void}
*/
init: function() {
if (typeof instance !== 'undefined') {
competencyframeworkid: frameworkId
}}
])[0].done(function(competencies) {
-
+ /**
+ * @param {Object} parent
+ * @param {Array} competencies
+ */
function addCompetencyChildren(parent, competencies) {
for (var i = 0; i < competencies.length; i++) {
if (competencies[i].parentid == parent.id) {
* Find a node in the dialogue.
*
* @param {String} selector
+ * @return {JQuery}
* @method _find
*/
Picker.prototype._find = function(selector) {
* Convenience method to get a framework object.
*
* @param {Number} fid The framework ID.
+ * @return {Object}
* @method _getFramework
*/
Picker.prototype._getFramework = function(fid) {
*
* This needs to be set after reset/close.
*
- * @params {Number[]} The IDs.
+ * @param {Number[]} ids The IDs.
* @method _setDisallowedCompetencyIDs
*/
Picker.prototype.setDisallowedCompetencyIDs = function(ids) {
* Trigger an event.
*
* @param {String} type The type of event.
- * @param {Object} The data to pass to the listeners.
+ * @param {Object} data The data to pass to the listeners.
* @method _reset
*/
Picker.prototype._trigger = function(type, data) {
/**
* Competency picker in plan class.
*
+ * @param {Number} userId
* @param {Number|false} singlePlan The ID of the plan when limited to one.
- * @param {String} pageContextIncludes One of 'children', 'parents', 'self'.
* @param {Boolean} multiSelect Support multi-select in the tree.
*/
var Picker = function(userId, singlePlan, multiSelect) {
* @param {Number} planId The planId.
* @param {String} searchText Limit the competencies to those matching the text.
* @method _fetchCompetencies
- * @return {Promise}
+ * @return {Promise} The promise object.
*/
Picker.prototype._fetchCompetencies = function(planId, searchText) {
var self = this;
*
* Triggered when a change occured.
*
- * @return {Void}
* @method _afterChange
* @protected
*/
*
* Triggered when a change occured in a specific rule config.
*
- * @return {Void}
* @method _afterRuleConfigChange
* @protected
+ * @param {Event} e
+ * @param {Rule} rule
*/
RuleConfig.prototype._afterRuleConfigChange = function(e, rule) {
if (rule != this._getRule()) {
/**
* After render hook.
*
- * @return {Promise}
* @method _afterRender
* @protected
*/
* Find a node in the dialogue.
*
* @param {String} selector
+ * @return {JQuery}
* @method _find
* @protected
*/
/**
* Set up the instance.
*
- * @return {Void}
* @method _setUp
* @protected
*/
/**
* Called when the user switches outcome.
*
- * @return {Void}
* @method _switchedOutcome
* @protected
*/
/**
* Called when the user switches rule.
*
- * @return {Void}
* @method _switchedRule
* @protected
*/
* Trigger an event.
*
* @param {String} type The type of event.
- * @param {Object} The data to pass to the listeners.
+ * @param {Object} data The data to pass to the listeners.
* @method _trigger
* @protected
*/
e.preventDefault();
templates.render('tool_lp/course_competency_settings', context).done(function(html) {
- str.get_string('configurecoursecompetencysettings', 'tool_lp').done(function (title) {
+ str.get_string('configurecoursecompetencysettings', 'tool_lp').done(function(title) {
this._dialogue = new Dialogue(
title,
html,
wide = false;
}
- Y.use('moodle-core-notification', 'timers', function () {
+ Y.use('moodle-core-notification', 'timers', function() {
var width = '480px';
if (wide) {
width = '800px';
/**
* Get content.
+ * @return {node}
*/
dialogue.prototype.getContent = function() {
return this.yuiDialogue.bodyNode.getDOMNode();
{ key: 'emptydragdropregion', component: 'moodle' },
{ key: 'movecontent', component: 'moodle' },
{ key: 'tocontent', component: 'moodle' },
- ]).done( function () {
- Y.use('moodle-tool_lp-dragdrop-reorder', function () {
+ ]).done(function() {
+ Y.use('moodle-tool_lp-dragdrop-reorder', function() {
var context = {
callback: callback
* Trigger an event.
*
* @param {String} type The type of event.
- * @param {Object} The data to pass to the listeners.
+ * @param {Object} data The data to pass to the listeners.
* @method _trigger
*/
Base.prototype._trigger = function(type, data) {
*
* @param {String} triggerSelector The node on which the click will happen.
* @param {String} containerSelector The parent node that will be removed and contains the evidence ID.
- * @return {Void}
*/
var register = function(triggerSelector, containerSelector) {
if (typeof selectors[triggerSelector] !== 'undefined') {
{ key: 'areyousure', component: 'moodle' },
{ key: 'delete', component: 'moodle' },
{ key: 'cancel', component: 'moodle' }
- ]).done(function (strings) {
+ ]).done(function(strings) {
Notification.confirm(
strings[0], // Confirm.
strings[1], // Are you sure?
}
}
}]);
- requests[0].done(function (success) {
+ requests[0].done(function(success) {
if (success === false) {
var req = ajax.call([{
methodname: 'core_competency_read_competency_framework',
args: { id: frameworkid }
}]);
- req[0].done(function (framework) {
+ req[0].done(function(framework) {
str.get_strings([
{ key: 'frameworkcannotbedeleted', component: 'tool_lp', param: framework.shortname },
{ key: 'cancel', component: 'moodle' }
- ]).done(function (strings) {
+ ]).done(function(strings) {
notification.alert(
null,
strings[0]
{ key: 'deletecompetencyframework', component: 'tool_lp', param: framework.shortname },
{ key: 'delete', component: 'moodle' },
{ key: 'cancel', component: 'moodle' }
- ]).done(function (strings) {
+ ]).done(function(strings) {
notification.confirm(
strings[0], // Confirm.
strings[1], // Delete competency framework X?
* @param {String} selector The selector of the auto complete element.
* @param {String} query The query string.
* @param {Function} callback A callback function receiving an array of results.
- * @return {Void}
*/
transport: function(selector, query, callback) {
var el = $(selector),
/**
* Grade dialogue class.
+ * @param {Array} ratingOptions
*/
var Grade = function(ratingOptions) {
EventBase.prototype.constructor.apply(this, []);
/**
* After render hook.
*
- * @return {Promise}
* @method _afterRender
* @protected
*/
*
* @param {String} selector
* @method _find
+ * @returns {node} The node
* @protected
*/
Grade.prototype._find = function(selector) {
* InlineEditor
*
* @param {String} selector The selector to trigger the grading.
- * @param {Number} The id of the scale for this competency.
- * @param {Number} The id of the competency.
- * @param {Number} The id of the user.
- * @param {Number} The id of the plan.
- * @param {Number} The id of the course.
- * @param {String} Language string for choose a rating.
+ * @param {Number} scaleId The id of the scale for this competency.
+ * @param {Number} competencyId The id of the competency.
+ * @param {Number} userId The id of the user.
+ * @param {Number} planId The id of the plan.
+ * @param {Number} courseId The id of the course.
+ * @param {String} chooseStr Language string for choose a rating.
*/
var InlineEditor = function(selector, scaleId, competencyId, userId, planId, courseId, chooseStr) {
EventBase.prototype.constructor.apply(this, []);
/**
* Constructor
*
- * @param {$} Jquery collection matching the root of the menu.
+ * @param {$} menuRoot Jquery collection matching the root of the menu.
* @param {Function[]} handlers, called when a menu item is chosen.
*/
var Menubar = function(menuRoot, handlers) {
* @method handleClick
* @param {Object} item is the jquery object of the item firing the event
* @param {Event} e is the associated event object
- * @return boolean Returns false
+ * @return {boolean} Returns false
*/
Menubar.prototype.handleClick = function(item, e) {
e.stopPropagation();
this.activeItem = null;
// Close the menu.
- this.menuRoot.find('ul').not('.root-level').attr('aria-hidden','true');
+ this.menuRoot.find('ul').not('.root-level').attr('aria-hidden', 'true');
// Follow any link, or call the click handlers.
var anchor = item.find('a').first();
var clickEvent = new $.Event('click');
subMenuContainer.css('margin-right', '-' + marginright + 'px');
}
} else {
- if ( pos.left + menuRealWidth > $(window).width()) {
+ if (pos.left + menuRealWidth > $(window).width()) {
marginleft = menuRealWidth - widthmenuRoot;
subMenuContainer.css('margin-left', '-' + marginleft + 'px');
}
return true;
}
- switch(e.keyCode) {
+ switch (e.keyCode) {
case this.keys.tab: {
// Hide all menu items and update their aria attributes.
// This is the root level move to next sibling. This will require closing
// the current child menu and opening the new one.
- if (menuIndex < menuNum-1) {
+ if (menuIndex < menuNum - 1) {
// Not the last root menu.
newItem = item.next();
} else { // Wrap to first item.
menuIndex = this.rootMenus.index(rootItem);
// If this is not the last root menu item, move to the next one.
- if (menuIndex < this.rootMenus.length-1) {
+ if (menuIndex < this.rootMenus.length - 1) {
newItem = rootItem.next();
} else {
// Loop.
// to the next item with a title that begins with that character.
if (startChr) {
var match = false;
- var curNdx = menuIndex+1;
+ var curNdx = menuIndex + 1;
// Check if the active item was the last one on the list.
if (curNdx == menuNum) {
// Iterate through the menu items (starting from the current item and wrapping) until a match is found
// or the loop returns to the current menu item.
- while (curNdx != menuIndex) {
+ while (curNdx != menuIndex) {
var titleChr = menuItems.eq(curNdx).html().charAt(0);
break;
}
- curNdx = curNdx+1;
+ curNdx = curNdx + 1;
if (curNdx == menuNum) {
// Reached the end of the list, start again at the beginning.
return item;
}
} else {
- if (menuIndex < menuNum-1) {
- newItem = menuItems.eq(menuIndex+1);
+ if (menuIndex < menuNum - 1) {
+ newItem = menuItems.eq(menuIndex + 1);
} else {
newItem = menuItems.first();
}
// If item is not the first item in its menu, move to the previous item.
if (menuIndex > 0) {
- newItem = menuItems.eq(menuIndex-1);
+ newItem = menuItems.eq(menuIndex - 1);
} else {
// Loop to top of menu.
newItem = menuItems.last();
* { "[data-action='add']" : callAddFunction }
*/
enhance: function(selector, handler) {
- $(selector).each(function (index, element) {
+ $(selector).each(function(index, element) {
var menuRoot = $(element);
// Don't enhance the same menu twice.
if (menuRoot.data("menubarEnhanced") !== true) {
/**
* Set the parent competency in the competency form.
*
- * @param {Object} Data containing selected cmpetency.
+ * @param {Object} data Data containing selected competency.
* @method setParent
*/
ParentCompetencyForm.prototype.setParent = function(data) {
/**
* Main initialisation.
* @param {String} buttonSelector The parent competency button selector.
- * @param {String} inputHiddenSelector The hidden input field selector.
+ * @param {String} inputSelector The hidden input field selector.
* @param {String} staticElementSelector The static element displaying the parent competency.
* @param {Number} frameworkId The competency framework ID.
* @param {Number} pageContextId The page context ID.
{ key: 'deleteplan', component: 'tool_lp', param: plan.name },
{ key: 'delete', component: 'moodle' },
{ key: 'cancel', component: 'moodle' }
- ]).done(function (strings) {
+ ]).done(function(strings) {
notification.confirm(
strings[0], // Confirm.
strings[1], // Delete plan X?
{ key: 'reopenplanconfirm', component: 'tool_lp', param: plan.name },
{ key: 'reopenplan', component: 'tool_lp' },
{ key: 'cancel', component: 'moodle' }
- ]).done(function (strings) {
+ ]).done(function(strings) {
notification.confirm(
strings[0], // Confirm.
strings[1], // Reopen plan X?
{ key: 'completeplanconfirm', component: 'tool_lp', param: plan.name },
{ key: 'completeplan', component: 'tool_lp' },
{ key: 'cancel', component: 'moodle' }
- ]).done(function (strings) {
+ ]).done(function(strings) {
notification.confirm(
strings[0], // Confirm.
strings[1], // Complete plan X?
{ key: 'unlinkplantemplateconfirm', component: 'tool_lp', param: plan.name },
{ key: 'unlinkplantemplate', component: 'tool_lp' },
{ key: 'cancel', component: 'moodle' }
- ]).done(function (strings) {
+ ]).done(function(strings) {
notification.confirm(
strings[0], // Confirm.
strings[1], // Unlink plan X?
courses: courses
};
templates.render('tool_lp/linked_courses_summary', context).done(function(html) {
- str.get_string('linkedcourses', 'tool_lp').done(function (linkedcourses) {
+ str.get_string('linkedcourses', 'tool_lp').done(function(linkedcourses) {
new Dialogue(
linkedcourses, // Title.
html // The linked courses.
*
* @name scaleChangeHandler
* @param {Event} e
- * @return {Void}
* @function
*/
ScaleConfig.prototype.scaleChangeHandler = function(e) {
* @param {Number} scaleid The scale id
* @return [] {Promise}
*/
-
+ // eslint-disable-next-line camelcase
get_values: function(scaleid) {
var deferred = $.Deferred();
if (typeof localCache[scaleid] === 'undefined') {
ajax.call([{
methodname: 'core_competency_get_scale_values',
- args: {scaleid : scaleid},
+ args: {scaleid: scaleid},
done: function(scaleinfo) {
localCache[scaleid] = scaleinfo;
deferred.resolve(scaleinfo);
* @copyright 2015 Damyon Wiese <damyon@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
-define(['jquery', 'core/templates', 'core/ajax', 'core/notification', 'core/str','tool_lp/actionselector'],
+define(['jquery', 'core/templates', 'core/ajax', 'core/notification', 'core/str', 'tool_lp/actionselector'],
function($, templates, ajax, notification, str, Actionselector) {
// Private variables and functions.
{ key: 'unlinkplanstemplate', component: 'tool_lp' },
{ key: 'confirm', component: 'moodle' },
{ key: 'cancel', component: 'moodle' }
- ]).done(function (strings) {
- var actions = [{'text': strings[2], 'value' : 'delete'},
- {'text': strings[3], 'value' : 'unlink'}];
+ ]).done(function(strings) {
+ var actions = [{'text': strings[2], 'value': 'delete'},
+ {'text': strings[3], 'value': 'unlink'}];
var actionselector = new Actionselector(
strings[0], // Title.
strings[1], // Message
doDelete();
});
}).fail(notification.exception);
- }
- else {
+ } else {
str.get_strings([
{ key: 'confirm', component: 'moodle' },
{ key: 'deletetemplate', component: 'tool_lp', param: template.shortname },
{ key: 'delete', component: 'moodle' },
{ key: 'cancel', component: 'moodle' }
- ]).done(function (strings) {
+ ]).done(function(strings) {
notification.confirm(
strings[0], // Confirm.
strings[1], // Delete learning plan template X?
var oneItem = null;
while (lastIndex < currentIndex) {
- oneItem = $(this.visibleItems.get(lastIndex));
+ oneItem = $(this.visibleItems.get(lastIndex));
oneItem.attr('aria-selected', 'true');
lastIndex++;
}
while (lastIndex > currentIndex) {
- oneItem = $(this.visibleItems.get(lastIndex));
+ oneItem = $(this.visibleItems.get(lastIndex));
oneItem.attr('aria-selected', 'true');
lastIndex--;
}
*/
Tree.prototype.toggleItem = function(item) {
if (!this.multiSelect) {
- return this.selectItem(item);
+ this.selectItem(item);
+ return;
}
var current = item.attr('aria-selected');
* @method handleKeyDown
* @param {Object} item is the jquery id of the parent item of the group
* @param {Event} e The event.
+ * @return {Boolean}
*/
Tree.prototype.handleKeyDown = function(item, e) {
var currentIndex = this.visibleItems.index(item);
* @method handleKeyPress
* @param {Object} item is the jquery id of the parent item of the group
* @param {Event} e The event.
+ * @return {Boolean}
*/
Tree.prototype.handleKeyPress = function(item, e) {
if (e.altKey || e.ctrlKey || e.shiftKey || e.metaKey) {
// Iterate through the menu items (starting from the current item and wrapping) until a match is found
// or the loop returns to the current menu item.
- while (currentIndex != itemIndex) {
+ while (currentIndex != itemIndex) {
var currentItem = this.visibleItems.eq(currentIndex);
var titleChr = currentItem.text().charAt(0);
break;
}
- currentIndex = currentIndex+1;
+ currentIndex = currentIndex + 1;
if (currentIndex == itemCount) {
// Reached the end of the list, start again at the beginning.
currentIndex = 0;
}
}
+ // eslint-disable-next-line no-unreachable
return true;
};
* @method handleDblClick
* @param {Object} item is the jquery id of the parent item of the group
* @param {Event} e The event.
+ * @return {Boolean}
*/
Tree.prototype.handleDblClick = function(item, e) {
* @method handleExpandCollapseClick
* @param {Object} item is the jquery id of the parent item of the group
* @param {Event} e The event.
+ * @return {Boolean}
*/
Tree.prototype.handleExpandCollapseClick = function(item, e) {
* @method handleClick
* @param {Object} item is the jquery id of the parent item of the group
* @param {Event} e The event.
+ * @return {Boolean}
*/
Tree.prototype.handleClick = function(item, e) {
* @method handleBlur
* @param {Object} item item is the jquery id of the parent item of the group
* @param {Event} e The event.
+ * @return {Boolean}
*/
Tree.prototype.handleBlur = function() {
return true;
* @method handleFocus
* @param {Object} item item is the jquery id of the parent item of the group
* @param {Event} e The event.
+ * @return {Boolean}
*/
Tree.prototype.handleFocus = function(item) {
/**
* UserCompetencyCourseNavigation
*
- * @param {String} The selector of the user element.
- * @param {String} The selector of the competency element.
- * @param {String} The base url for the page (no params).
- * @param {Number} The course id
- * @param {Number} The user id
- * @param {Number} The competency id
+ * @param {String} userSelector The selector of the user element.
+ * @param {String} competencySelector The selector of the competency element.
+ * @param {String} baseUrl The base url for the page (no params).
+ * @param {Number} userId The user id
+ * @param {Number} competencyId The competency id
+ * @param {Number} courseId The course id
*/
var UserCompetencyCourseNavigation = function(userSelector, competencySelector, baseUrl, userId, competencyId, courseId) {
this._baseUrl = baseUrl;
/**
* Info
*
- * @param {JQuery} Selector to replace when the information needs updating.
- * @param {Number} The id of the competency.
- * @param {Number} The id of the user.
- * @param {Number} The id of the plan.
- * @param {Number} The id of the course.
- * @param {Boolean} If we should display the user info.
+ * @param {JQuery} rootElement Selector to replace when the information needs updating.
+ * @param {Number} competencyId The id of the competency.
+ * @param {Number} userId The id of the user.
+ * @param {Number} planId The id of the plan.
+ * @param {Number} courseId The id of the course.
+ * @param {Boolean} displayuser If we should display the user info.
*/
var Info = function(rootElement, competencyId, userId, planId, courseId, displayuser) {
this._rootElement = rootElement;
/**
* UserCompetencyPopup
*
- * @param {String} The regionSelector
- * @param {String} The userCompetencySelector
- * @param {Number} The plan ID
+ * @param {String} regionSelector The regionSelector
+ * @param {String} userCompetencySelector The userCompetencySelector
+ * @param {Number} planId The plan ID
*/
var UserCompetencyPopup = function(regionSelector, userCompetencySelector, planId) {
this._regionSelector = regionSelector;
var planId = this._planId;
var requests = ajax.call([{
- methodname : 'tool_lp_data_for_user_competency_summary_in_plan',
+ methodname: 'tool_lp_data_for_user_competency_summary_in_plan',
args: { competencyid: competencyId, planid: planId },
done: this._contextLoaded.bind(this),
fail: notification.exception
}]);
// Log the user competency viewed in plan event.
- requests[0].then(function (result) {
+ requests[0].then(function(result) {
var eventMethodName = 'core_competency_user_competency_viewed_in_plan';
// Trigger core_competency_user_competency_plan_viewed event instead if plan is already completed.
if (result.plan.iscompleted) {
var planId = this._planId;
ajax.call([{
- methodname : 'tool_lp_data_for_plan_page',
+ methodname: 'tool_lp_data_for_plan_page',
args: { planid: planId},
done: this._pageContextLoaded.bind(this),
fail: notification.exception
* Cancel a review request and refresh the view.
*
* @param {Object} data The user competency data.
- * @return {Void}
* @method _cancelReviewRequest
*/
UserCompetencyWorkflow.prototype._cancelReviewRequest = function(data) {
* Cancel a review request an refresh the view.
*
* @param {Object} data The user competency data.
- * @return {Void}
* @method cancelReviewRequest
*/
UserCompetencyWorkflow.prototype.cancelReviewRequest = function(data) {
* Cancel a review request handler.
*
* @param {Event} e The event.
- * @return {Void}
* @method _cancelReviewRequestHandler
*/
UserCompetencyWorkflow.prototype._cancelReviewRequestHandler = function(e) {
* Request a review and refresh the view.
*
* @param {Object} data The user competency data.
- * @return {Void}
* @method _requestReview
*/
UserCompetencyWorkflow.prototype._requestReview = function(data) {
* Request a review.
*
* @param {Object} data The user competency data.
- * @return {Void}
* @method requestReview
*/
UserCompetencyWorkflow.prototype.requestReview = function(data) {
* Request a review handler.
*
* @param {Event} e The event.
- * @return {Void}
* @method _requestReviewHandler
*/
UserCompetencyWorkflow.prototype._requestReviewHandler = function(e) {
* Start a review and refresh the view.
*
* @param {Object} data The user competency data.
- * @return {Void}
* @method _startReview
*/
UserCompetencyWorkflow.prototype._startReview = function(data) {
* Start a review.
*
* @param {Object} data The user competency data.
- * @return {Void}
* @method startReview
*/
UserCompetencyWorkflow.prototype.startReview = function(data) {
* Start a review handler.
*
* @param {Event} e The event.
- * @return {Void}
* @method _startReviewHandler
*/
UserCompetencyWorkflow.prototype._startReviewHandler = function(e) {
* Stop a review and refresh the view.
*
* @param {Object} data The user competency data.
- * @return {Void}
* @method _stopReview
*/
UserCompetencyWorkflow.prototype._stopReview = function(data) {
* Stop a review.
*
* @param {Object} data The user competency data.
- * @return {Void}
* @method stopReview
*/
UserCompetencyWorkflow.prototype.stopReview = function(data) {
* Stop a review handler.
*
* @param {Event} e The event.
- * @return {Void}
* @method _stopReviewHandler
*/
UserCompetencyWorkflow.prototype._stopReviewHandler = function(e) {
{ key: 'deleteuserevidence', component: 'tool_lp', param: evidence.name },
{ key: 'delete', component: 'moodle' },
{ key: 'cancel', component: 'moodle' }
- ]).done(function (strings) {
+ ]).done(function(strings) {
notification.confirm(
strings[0], // Confirm.
strings[1], // Delete evidence X?
{ key: 'sendallcompetenciestoreview', component: 'tool_lp', param: evidence.name },
{ key: 'confirm', component: 'moodle' },
{ key: 'cancel', component: 'moodle' }
- ]).done(function (strings) {
+ ]).done(function(strings) {
notification.confirm(
strings[0], // Confirm.
strings[1], // Send all competencies in review for X?
}
protected function get_other_values(renderer_base $output) {
- $context = $this->related['cm']->context;
+ $cm = $this->related['cm'];
+ $context = $cm->context;
- return array(
- 'id' => $this->related['cm']->id,
- 'name' => external_format_string($this->related['cm']->name, $context->id),
- 'url' => $this->related['cm']->url->out(),
- 'iconurl' => $this->related['cm']->get_icon_url()->out()
+ $values = array(
+ 'id' => $cm->id,
+ 'name' => external_format_string($cm->name, $context->id),
+ 'iconurl' => $cm->get_icon_url()->out()
);
+ if ($cm->url) {
+ $values['url'] = $cm->url->out();
+ }
+ return $values;
}
'type' => PARAM_TEXT
),
'url' => array(
- 'type' => PARAM_URL
+ 'type' => PARAM_URL,
+ 'optional' => true,
),
'iconurl' => array(
'type' => PARAM_URL
.tool-lp-menu li {
float: left;
- display: inline;
position: relative;
list-style-type: none;
white-space: nowrap;
$result = external::get_plugins_supporting_mobile();
$result = external_api::clean_returnvalue(external::get_plugins_supporting_mobile_returns(), $result);
$this->assertCount(0, $result['warnings']);
- $this->assertCount(0, $result['plugins']);
+ $this->assertArrayHasKey('plugins', $result);
+ $this->assertTrue(is_array($result['plugins']));
}
}
var promises = ajax.call([{
methodname: 'core_output_load_template',
- args:{
+ args: {
component: component,
template: name,
themename: config.theme
}
}, {
methodname: 'tool_templatelibrary_load_canonical_template',
- args:{
+ args: {
component: component,
template: name
}
// When returns a new promise that is resolved when all the passed in promises are resolved.
// The arguments to the done become the values of each resolved promise.
$.when.apply($, promises)
- .done( function(source, originalSource) { templateLoaded(templateName, source, originalSource); })
+ .done(function(source, originalSource) {
+ templateLoaded(templateName, source, originalSource);
+ })
.fail(notification.exception);
};
// Add the event listeners.
- $('[data-region="list-templates"]').on('click', '[data-templatename]', function() {
+ $('[data-region="list-templates"]').on('click', '[data-templatename]', function(e) {
var templatename = $(this).data('templatename');
+ e.preventDefault();
loadTemplate(templatename);
});
* The ajax call has returned with a new list of templates.
*
* @method reloadListTemplate
- * @param String[] templates List of template ids.
+ * @param {String[]} templateList List of template ids.
*/
var reloadListTemplate = function(templateList) {
templates.render('tool_templatelibrary/search_results', { templates: templateList })
- .done(function (result, js) {
+ .done(function(result, js) {
templates.replaceNode($('[data-region="searchresults"]'), result, js);
}).fail(notification.exception);
};
* the function will only be executed once.
*
* @method queueRefresh
- * @param function callback
- * @param int delay The time in milliseconds to delay.
+ * @param {function} callback
+ * @param {Number} delay The time in milliseconds to delay.
*/
var queueRefresh = function(callback, delay) {
if (throttle !== null) {
#page-blocks-community-communitycourse .hubtext {display: block; width: 68%; padding-left: 165px;}
#page-blocks-community-communitycourse .hubimgandtext {display:table;}
#page-blocks-community-communitycourse .hubimage {float: left; display: block; width: 100px;}
-#page-blocks-community-communitycourse .hubdescriptiontext {}
#page-blocks-community-communitycourse .hubstats {padding-top: 10px}
#page-blocks-community-communitycourse .hubstats .iconhelp {float: left; padding-right: 3px;}
#page-blocks-community-communitycourse .hubadditionaldesc {color: #666666; font-size: 90%; display:block;}
#page-blocks-community-communitycourse .hubscreenshot {margin-right: 10px;}
-#page-blocks-community-communitycourse .hubnottrusted {}
#page-blocks-community-communitycourse .hubtrusted {display:inline;}
-#page-blocks-community-communitycourse .hubnottrusted {}
#page-blocks-community-communitycourse .trustedtr {background-color: #ffe1c3;}
#page-blocks-community-communitycourse .prioritisetr {background-color: #ffd4ff;}
#page-blocks-community-communitycourse .blockdescription {font-size: 80%; color: #555555;}
#page-blocks-community-communitycourse .comment-link {font-size: 80%; color: #555555;}
#page-blocks-community-communitycourse .coursescreenshot {text-align:center;cursor: pointer;}
#page-blocks-community-communitycourse .hubcourseinfo {margin-left: 15px;}
-#page-blocks-community-communitycourse .coursesitelink {}
#page-blocks-community-communitycourse .pagingbar {text-align: center;}
#page-blocks-community-communitycourse .coursecomment {float: right;}
#page-blocks-community-communitycourse .courseoperations {margin-top:9px; text-align:center}
font-size: 95%;
margin-bottom: 9px;
}
-#page-blocks-community-communitycourse .comment-list li {
- background-color:#FFFAFA !important;
- -moz-border-radius: 6px;
- -webkit-border-radius: 6px;
- padding-right: 4px;
- padding-bottom: 2px;
-}
/* STAR RATING */
#page-blocks-community-communitycourse .ratingcount {color: #8B8989;font-size: 80%;vertical-align: top;}
margin-top:15px;
}
#page-blocks-community-communitycourse .hubrateandcomment { font-size: 80%;}
-#page-blocks-community-communitycourse .hubcourseoutcomes {}
#page-blocks-community-communitycourse .nextlink {text-align: center;margin-top: 6px;}
#page-blocks-community-communitycourse .textinfo { text-align: center;}
// Copied from lib/navigationlib.php navigation_node constants.
var NODETYPE = {
// @type int Activity (course module) = 40.
- ACTIVITY : 40,
+ ACTIVITY: 40,
// @type int Resource (course module = 50.
- RESOURCE : 50,
+ RESOURCE: 50,
};
/**
* @method buildDOM
* @param {Object} rootElement the root element of DOM.
* @param {object} nodes jquery object representing the nodes to be build.
- * @return
*/
function buildDOM(rootElement, nodes) {
var ul = $('<ul></ul>');
if (icon) {
link.append(icon);
- link.append('<span class="item-content-wrap">'+node.name+'</span>');
+ link.append('<span class="item-content-wrap">' + node.name + '</span>');
} else {
link.append(node.name);
}
if (icon) {
span.append(icon);
- span.append('<span class="item-content-wrap">'+node.name+'</span>');
+ span.append('<span class="item-content-wrap">' + node.name + '</span>');
} else {
span.append(node.name);
}
* Get the block instance id.
*
* @function getBlockInstanceId
- * @param element
- * @returns {*}
+ * @param {Element} element
+ * @returns {String} the instance id
*/
function getBlockInstanceId(element) {
return element.closest('[data-block]').attr('data-instanceid');
-@block @block_private_files @file_upload @javascript
+@block @block_private_files @_file_upload @javascript
Feature: The private files block allows users to store files privately in moodle
In order to store a private file in moodle
As a user
-@block @block_private_files @file_upload
+@block @block_private_files @_file_upload
Feature: The private files block allows users to store files privately in moodle
In order to store a private file in moodle
As a teacher
} else if (!empty($options->courseid)) {
$this->courseid = $options->courseid;
} else {
- $this->courseid = SITEID;
+ if ($coursecontext = $this->context->get_course_context(false)) {
+ $this->courseid = $coursecontext->instanceid;
+ } else {
+ $this->courseid = SITEID;
+ }
}
// setup coursemodule
* @param int $limit Number of records to return.
* @return \core_competency\evidence[]
*/
- public static function list_evidence_in_course($userid = 0, $courseid = 0, $competencyid = 0, $sort = 'timecreated',
+ public static function list_evidence_in_course($userid = 0, $courseid = 0, $competencyid = 0, $sort = 'timecreated, id',
$order = 'DESC', $skip = 0, $limit = 0) {
static::require_enabled();
return array();
}
- $params = array(
- 'usercompetencyid' => $usercompetency->get_id(),
- 'contextid' => context_course::instance($courseid)->id
- );
- return evidence::get_records($params, $sort, $order, $skip, $limit);
+ $context = context_course::instance($courseid);
+ return evidence::get_records_for_usercompetency($usercompetency->get_id(), $context, $sort, $order, $skip, $limit);
}
/**
return has_capability('moodle/competency:evidencedelete', context_user::instance($userid));
}
+ /**
+ * Load a list of records in a context for a user competency.
+ *
+ * @param int $usercompetencyid The id of the user competency.
+ * @param context $context Context to filter the evidence list.
+ * @param string $sort The field from the evidence table to sort on.
+ * @param string $order The sort direction
+ * @param int $skip Limitstart.
+ * @param int $limit Number of rows to return.
+ *
+ * @return \core_competency\persistent[]
+ */
+ public static function get_records_for_usercompetency($usercompetencyid,
+ \context $context,
+ $sort = '',
+ $order = 'ASC',
+ $skip = 0,
+ $limit = 0) {
+ global $DB;
+
+ $params = array(
+ 'usercompid' => $usercompetencyid,
+ 'path' => $context->path . '/%',
+ 'contextid' => $context->id
+ );
+
+ if (!empty($sort)) {
+ $sortcolumns = explode(',', $sort);
+ $sortcolumns = array_map('trim', $sortcolumns);
+ $sort = ' ORDER BY e.' . implode(', e.', $sortcolumns) . ' ' . $order;
+ }
+
+ $sql = 'SELECT e.*
+ FROM {' . static::TABLE . '} e
+ JOIN {context} c ON c.id = e.contextid
+ WHERE (c.path LIKE :path OR c.id = :contextid)
+ AND e.usercompetencyid = :usercompid
+ ' . $sort;
+ $records = $DB->get_records_sql($sql, $params, $skip, $limit);
+ $instances = array();
+
+ foreach ($records as $record) {
+ $newrecord = new static(0, $record);
+ array_push($instances, $newrecord);
+ }
+ return $instances;
+ }
+
}
$this->assertEquals(null, $ev4->get_actionuserid());
}
+ public function test_list_evidence_in_course() {
+ global $SITE;
+
+ $this->resetAfterTest(true);
+ $dg = $this->getDataGenerator();
+ $lpg = $dg->get_plugin_generator('core_competency');
+ $u1 = $dg->create_user();
+ $course = $dg->create_course();
+ $coursecontext = context_course::instance($course->id);
+
+ $this->setAdminUser();
+ $f = $lpg->create_framework();
+ $c = $lpg->create_competency(array('competencyframeworkid' => $f->get_id()));
+ $c2 = $lpg->create_competency(array('competencyframeworkid' => $f->get_id()));
+ $cc = api::add_competency_to_course($course->id, $c->get_id());
+ $cc2 = api::add_competency_to_course($course->id, $c2->get_id());
+
+ $pagegenerator = $this->getDataGenerator()->get_plugin_generator('mod_page');
+ $page = $pagegenerator->create_instance(array('course' => $course->id));
+
+ $cm = get_coursemodule_from_instance('page', $page->id);
+ $cmcontext = context_module::instance($cm->id);
+ // Add the competency to the course module.
+ $ccm = api::add_competency_to_course_module($cm, $c->get_id());
+
+ // Now add the evidence to the course.
+ $evidence1 = api::add_evidence($u1->id, $c->get_id(), $coursecontext->id, \core_competency\evidence::ACTION_LOG,
+ 'invaliddata', 'error');
+
+ $result = api::list_evidence_in_course($u1->id, $course->id, $c->get_id());
+ $this->assertEquals($result[0]->get_id(), $evidence1->get_id());
+
+ // Now add the evidence to the course module.
+ $evidence2 = api::add_evidence($u1->id, $c->get_id(), $cmcontext->id, \core_competency\evidence::ACTION_LOG,
+ 'invaliddata', 'error');
+
+ $result = api::list_evidence_in_course($u1->id, $course->id, $c->get_id());
+ $this->assertEquals($result[0]->get_id(), $evidence2->get_id());
+ $this->assertEquals($result[1]->get_id(), $evidence1->get_id());
+ }
+
public function test_list_course_modules_using_competency() {
global $SITE;
*/
public function config_form_display(&$mform, $data = null) {
$modnames = get_module_types_names();
- $mform->addElement('checkbox', 'criteria_activity['.$data->id.']',
- $modnames[self::get_mod_name($data->module)].
- ' - '.
- format_string($data->name));
+ $mform->addElement('advcheckbox',
+ 'criteria_activity['.$data->id.']',
+ $modnames[self::get_mod_name($data->module)] . ' - ' . format_string($data->name),
+ null,
+ array('group' => 1));
if ($this->id) {
$mform->setDefault('criteria_activity['.$data->id.']', 1);
"require-dev": {
"phpunit/phpunit": "4.8.*",
"phpunit/dbUnit": "1.4.*",
- "moodlehq/behat-extension": "3.32.0"
+ "moodlehq/behat-extension": "3.32.1"
}
}
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
- "hash": "0bd3021c5dea5e28a07d7a58d0f1676d",
- "content-hash": "528abab2d8628a8442924ec3defc561d",
+ "hash": "949f8a407958a19e2dba7929b3dc0576",
+ "content-hash": "bd742592f8ed4700884f6c651226c961",
"packages": [],
"packages-dev": [
{
},
{
"name": "moodlehq/behat-extension",
- "version": "v3.32.0",
+ "version": "v3.32.1",
"source": {
"type": "git",
"url": "https://github.com/moodlehq/moodle-behat-extension.git",
- "reference": "f0b6a44de9111fd4fa82796aca712b9e9772d07e"
+ "reference": "f8305058ce9140864c23c9b667e3d7d487fdc006"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/moodlehq/moodle-behat-extension/zipball/f0b6a44de9111fd4fa82796aca712b9e9772d07e",
- "reference": "f0b6a44de9111fd4fa82796aca712b9e9772d07e",
+ "url": "https://api.github.com/repos/moodlehq/moodle-behat-extension/zipball/f8305058ce9140864c23c9b667e3d7d487fdc006",
+ "reference": "f8305058ce9140864c23c9b667e3d7d487fdc006",
"shasum": ""
},
"require": {
"Behat",
"moodle"
],
- "time": "2016-05-09 03:32:06"
+ "time": "2016-06-20 07:56:08"
},
{
"name": "phpdocumentor/reflection-docblock",
},
{
"name": "sebastian/exporter",
- "version": "1.2.1",
+ "version": "1.2.2",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/exporter.git",
- "reference": "7ae5513327cb536431847bcc0c10edba2701064e"
+ "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/7ae5513327cb536431847bcc0c10edba2701064e",
- "reference": "7ae5513327cb536431847bcc0c10edba2701064e",
+ "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/42c4c2eec485ee3e159ec9884f95b431287edde4",
+ "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4",
"shasum": ""
},
"require": {
"sebastian/recursion-context": "~1.0"
},
"require-dev": {
+ "ext-mbstring": "*",
"phpunit/phpunit": "~4.4"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.2.x-dev"
+ "dev-master": "1.3.x-dev"
}
},
"autoload": {
"export",
"exporter"
],
- "time": "2015-06-21 07:55:53"
+ "time": "2016-06-17 09:04:28"
},
{
"name": "sebastian/global-state",
$activities = $completion->get_activities();
if (!empty($activities)) {
+ if (!$completion->is_course_locked()) {
+ $this->add_checkbox_controller(1, null, null, 0);
+ }
foreach ($activities as $activity) {
$params_a = array('moduleinstance' => $activity->id);
$criteria = new completion_criteria_activity(array_merge($params, $params_a));
If this file exists it will be included in the CSS Moodle generates.
-
-Optional delete course hook
----------------------------
-
-* in your yourformat/lib.php add function format_yourformat_delete_course($courseid)
\ No newline at end of file
Then I should see "Use default section name [Topic 2]"
Scenario: Edit section summary in topics format
- When I edit the section "2"
- And I set the following fields to these values:
+ When I edit the section "2" and I fill the form with:
| Summary | Welcome to section 2 |
- And I press "Save changes"
Then I should see "Welcome to section 2" in the "li#section-2" "css_element"
Scenario: Edit section default name in topics format
- When I edit the section "2"
- And I set the following fields to these values:
+ When I edit the section "2" and I fill the form with:
| Use default section name | 0 |
| name | This is the second topic |
- And I press "Save changes"
Then I should see "This is the second topic" in the "li#section-2" "css_element"
And I should not see "Topic 2" in the "li#section-2" "css_element"
Overview of this plugin type at http://docs.moodle.org/dev/Course_formats
+=== 3.2 ===
+* Callback delete_course is deprecated and should be replaced with observer for event \core\event\course_content_deleted
+
=== 3.1 ===
* Course format may use the inplace_editable template to allow quick editing of section names, see
https://docs.moodle.org/dev/Inplace_editable and MDL-51802 for example implementation.
public function __construct(moodle_page $page, $target) {
$this->strings = new stdClass;
parent::__construct($page, $target);
- $this->add_modchoosertoggle();
}
/**
*
* Theme can overwrite as an empty function to exclude it (for example if theme does not
* use modchooser at all)
+ *
+ * @deprecated since 3.2
*/
protected function add_modchoosertoggle() {
+ debugging('core_course_renderer::add_modchoosertoggle() is deprecated.', DEBUG_DEVELOPER);
+
global $CFG;
// Only needs to be done once per page.
array(array('courseid' => $course->id, 'closeButtonTitle' => get_string('close', 'editor')))
);
$this->page->requires->strings_for_js(array(
- 'addresourceoractivity',
- 'modchooserenable',
- 'modchooserdisable',
+ 'addresourceoractivity'
), 'moodle');
// Add the header
/**
* Renders HTML for the menus to add activities and resources to the current course
*
- * Note, if theme overwrites this function and it does not use modchooser,
- * see also {@link core_course_renderer::add_modchoosertoggle()}
- *
* @param stdClass $course
* @param int $section relative section number (field course_sections.section)
* @param int $sectionreturn The section to link back to
public function i_edit_the_section_and_i_fill_the_form_with($sectionnumber, TableNode $data) {
// Edit given section.
- $this->execute("behat_course::i_edit_the_section");
+ $this->execute("behat_course::i_edit_the_section", $sectionnumber);
// Set form fields.
$this->execute("behat_forms::i_set_the_following_fields_to_these_values", $data);
And I log in as "teacher1"
And I follow "Course 1"
When I turn editing mode on
- And I follow "Activity chooser off"
Then the "Add an activity to section 'Topic 1'" select box should not contain "Chat"
Then the "Add an activity to section 'Topic 1'" select box should not contain "Glossary"
$move = optional_param('move', 0, PARAM_INT);
$marker = optional_param('marker',-1 , PARAM_INT);
$switchrole = optional_param('switchrole',-1, PARAM_INT); // Deprecated, use course/switchrole.php instead.
- $modchooser = optional_param('modchooser', -1, PARAM_BOOL);
$return = optional_param('return', 0, PARAM_LOCALURL);
$params = array();
redirect($PAGE->url);
}
}
- if (($modchooser == 1) && confirm_sesskey()) {
- set_user_preference('usemodchooser', $modchooser);
- } else if (($modchooser == 0) && confirm_sesskey()) {
- set_user_preference('usemodchooser', $modchooser);
- }
if (has_capability('moodle/course:sectionvisibility', $context)) {
if ($hide && confirm_sesskey()) {
// Initialize existing sections and register for dynamically created sections
this.setup_for_section();
M.course.coursebase.register_module(this);
-
- // Catch the page toggle
- Y.all('.block_settings #settingsnav .type_course .modchoosertoggle a').on('click', this.toggle_mod_chooser, this);
},
/**
this.display_chooser(e);
},
- /**
- * Toggle availability of the activity chooser.
- *
- * @method toggle_mod_chooser
- * @param {EventFacade} e
- */
- toggle_mod_chooser : function(e) {
- // Get the add section link
- var modchooserlinks = Y.all('div.addresourcemodchooser');
-
- // Get the dropdowns
- var dropdowns = Y.all('div.addresourcedropdown');
-
- if (modchooserlinks.size() === 0) {
- // Continue with non-js action if there are no modchoosers to add
- return;
- }
-
- // We need to update the text and link
- var togglelink = Y.one('.block_settings #settingsnav .type_course .modchoosertoggle a');
-
- // The actual text is in the last child
- var toggletext = togglelink.get('lastChild');
-
- var usemodchooser;
- // Determine whether they're currently hidden
- if (modchooserlinks.item(0).hasClass('visibleifjs')) {
- // The modchooser is currently visible, hide it
- usemodchooser = 0;
- modchooserlinks
- .removeClass('visibleifjs')
- .addClass('hiddenifjs');
- dropdowns
- .addClass('visibleifjs')
- .removeClass('hiddenifjs');
- toggletext.set('data', M.util.get_string('modchooserenable', 'moodle'));
- togglelink.set('href', togglelink.get('href').replace('off', 'on'));
- } else {
- // The modchooser is currently not visible, show it
- usemodchooser = 1;
- modchooserlinks
- .addClass('visibleifjs')
- .removeClass('hiddenifjs');
- dropdowns
- .removeClass('visibleifjs')
- .addClass('hiddenifjs');
- toggletext.set('data', M.util.get_string('modchooserdisable', 'moodle'));
- togglelink.set('href', togglelink.get('href').replace('on', 'off'));
- }
-
- M.util.set_user_preference('usemodchooser', usemodchooser);
-
- // Prevent the page from reloading
- e.preventDefault();
- },
-
/**
* Helper function to set the value of a hidden radio button when a
* selection is made.
array($this->escape($enrolmethod), get_string('addinstance', 'enrol'))
);
+ // Wait again, for page to reloaded.
+ $this->execute('behat_general::i_wait_to_be_redirected');
+
// Set form fields.
$this->execute("behat_forms::i_set_the_following_fields_to_these_values", $table);
/**
* Filters
*/
-.mediaplugin_html5audio, .mediaplugin_html5video, .mediaplugin_swf, .mediaplugin_flv, .mediaplugin_real, .mediaplugin_youtube, .mediaplugin_vimeo, .mediaplugin_wmp, .mediaplugin_qt
- {display:block;margin-top:5px;margin-bottom:5px;text-align: center;}
-.mediaplugin.mediaplugin_mp3 object {display:inline;height:15px;width:180px;margin-left:0.5em;}
-
+.mediaplugin_html5audio,
+.mediaplugin_html5video,
+.mediaplugin_swf,
+.mediaplugin_flv,
+.mediaplugin_real,
+.mediaplugin_youtube,
+.mediaplugin_vimeo,
+.mediaplugin_wmp,
+.mediaplugin_qt {
+ display: block;
+ margin-top: 5px;
+ margin-bottom: 5px;
+ text-align: center;
+}
/*
* mp3 player colours -this read using JS and applied to swf audio flow player
* see http://flowplayer.org/documentation/skinning/controlbar.html?skin=default for more color properties,
* any property that ends with '...Color' is supported here.
*/
-.mp3flowplayer_backgroundColor {color: #000000;}
+.mp3flowplayer_backgroundColor {
+ color: #000000;
+}
* @copyright 2015 Jun Pataleta <jun@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
-define(['jquery', 'core/templates', 'core/notification', 'core/yui'], function ($, templates, notification) {
+define(['jquery', 'core/templates', 'core/notification', 'core/yui'], function($, templates, notification) {
// Private variables and functions.
* Basically, it performs the binding and handling of the button click event for
* the 'Insert frequently used comment' button.
*
- * @param criterionId The criterion ID.
- * @param buttonId The element ID of the button which the handler will be bound to.
- * @param remarkId The element ID of the remark text area where the text of the selected comment will be copied to.
- * @param commentOptions The array of frequently used comments to be used as options.
+ * @param {Integer} criterionId The criterion ID.
+ * @param {String} buttonId The element ID of the button which the handler will be bound to.
+ * @param {String} remarkId The element ID of the remark text area where the text of the selected comment will be copied to.
+ * @param {Array} commentOptions The array of frequently used comments to be used as options.
*/
- initialise: function (criterionId, buttonId, remarkId, commentOptions) {
+ initialise: function(criterionId, buttonId, remarkId, commentOptions) {
/**
* Display the chooser dialog using the compiled HTML from the mustache template
* and binds onclick events for the generated comment options.
*
- * @param compiledSource The compiled HTML from the mustache template
- * @param comments Array containing comments.
+ * @param {String} compiledSource The compiled HTML from the mustache template
+ * @param {Array} comments Array containing comments.
*/
function displayChooserDialog(compiledSource, comments) {
var titleLabel = '<label>' + M.util.get_string('insertcomment', 'gradingform_guide') + '</label>';
});
// Loop over each comment item and bind click events.
- $.each(comments, function (index, comment) {
+ $.each(comments, function(index, comment) {
var commentOptionId = '#comment-option-' + criterionId + '-' + comment.id;
// Delegate click event for the generated option link.
- $(commentOptionId).click(function () {
+ $(commentOptionId).click(function() {
var remarkTextArea = $('#' + remarkId);
var remarkText = remarkTextArea.val();
});
// Handle keypress on list items.
- $(document).off('keypress', commentOptionId).on('keypress', commentOptionId, function () {
+ $(document).off('keypress', commentOptionId).on('keypress', commentOptionId, function() {
var keyCode = event.which || event.keyCode;
// Enter or space key.
// Render the template and display the comment chooser dialog.
templates.render('gradingform_guide/comment_chooser', context)
- .done(function (compiledSource) {
+ .done(function(compiledSource) {
displayChooserDialog(compiledSource, commentOptions);
})
.fail(notification.exception);
}
// Bind click event for the comments chooser button.
- $("#" + buttonId).click(function (e) {
+ $("#" + buttonId).click(function(e) {
e.preventDefault();
generateCommentsChooser();
});
$string['hidemarkerdesc'] = 'Hide marker criterion descriptions';
$string['hidestudentdesc'] = 'Hide student criterion descriptions';
$string['insertcomment'] = 'Insert frequently used comment';
-$string['maxscore'] = 'Maximum mark';
+$string['maxscore'] = 'Maximum score';
$string['name'] = 'Name';
$string['needregrademessage'] = 'The marking guide definition was changed after this student had been graded. The student can not see this marking guide until you check the marking guide and update the grade.';
$string['pluginname'] = 'Marking guide';
* @param TableNode $guide
*/
public function i_define_the_following_marking_guide(TableNode $guide) {
- $steptableinfo = '| Criterion name | Description for students | Description for markers | Maximum mark |';
+ $steptableinfo = '| Criterion name | Description for students | Description for markers | Maximum score |';
if ($criteria = $guide->getHash()) {
$addcriterionbutton = $this->find_button(get_string('addcriterion', 'gradingform_guide'));
$this->set_guide_field_value($criterionroot . '[descriptionmarkers]', $criterion['Description for markers']);
// Set the field value for the Max score field.
- $this->set_guide_field_value($criterionroot . '[maxscore]', $criterion['Maximum mark']);
+ $this->set_guide_field_value($criterionroot . '[maxscore]', $criterion['Maximum score']);
}
}
}
| Name | Assignment 1 marking guide |
| Description | Marking guide test description |
And I define the following marking guide:
- | Criterion name | Description for students | Description for markers | Maximum mark |
- | Guide criterion A | Guide A description for students | Guide A description for markers | 30 |
- | Guide criterion B | Guide B description for students | Guide B description for markers | 30 |
- | Guide criterion C | Guide C description for students | Guide C description for markers | 40 |
+ | Criterion name | Description for students | Description for markers | Maximum score |
+ | Guide criterion A | Guide A description for students | Guide A description for markers | 30 |
+ | Guide criterion B | Guide B description for students | Guide B description for markers | 30 |
+ | Guide criterion C | Guide C description for students | Guide C description for markers | 40 |
And I define the following frequently used comments:
| Comment 1 |
| Comment 2 |
if (isset($user)) {
$output = $OUTPUT->context_header(
array(
- 'heading' => fullname($user),
+ 'heading' => html_writer::link(new moodle_url('/user/view.php', array('id' => $user->id,
+ 'course' => $courseid)), fullname($user)),
'user' => $user,
'usercontext' => context_user::instance($user->id)
), 2
.dir-rtl.path-grade-report-grader .gradeparent table {
border-left-width: 0;
border-right-width: 1px;
- max-width: initial;
}
/**
.path-grade-report-grader .yui3-overlay {
border: 0;
background: none;
- background-color: initial;
+ background-color: inherit;
min-width: 200px;
}
| grade_report_showaverages | 0 |
| grade_report_enableajax | 1 |
-
@javascript
Scenario: Use the grader report without editing, with AJAX on and quick feedback off
When the following config values are set as admin:
return this;
}
+ if (M.cfg.behatsiterunning) {
+ // If the behat site is running we don't want floating elements.
+ return;
+ }
+
// Generate floating elements.
this._setupFloatingUserColumn();
this._setupFloatingUserHeader();
.path-grade-report-singleview .itemnav {
font-size: small;
display: inline;
- margin-bottom: 0.5em;
+ padding-bottom: 0.5em;
}
.path-grade-report-singleview itemnav.previtem {
float:left;
var parentEl = document.getElementById(parentId);
if (parentEl) {
var loader = document.getElementById("loaderImg");
- parentEl.removeChild(loader);
+ if (loader) {
+ parentEl.removeChild(loader);
+ }
}
};
--- /dev/null
+<?php
+
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Automatically generated strings for Moodle installer
+ *
+ * Do not edit this file manually! It contains just a subset of strings
+ * needed during the very first steps of installation. This file was
+ * generated automatically by export-installer.php (which is part of AMOS
+ * {@link http://docs.moodle.org/dev/Languages/AMOS}) using the
+ * list of strings defined in /install/stringnames.txt.
+ *
+ * @package installer
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+$string['parentlanguage'] = 'da';
+$string['thisdirection'] = 'ltr';
+$string['thislanguage'] = 'Dansk Rum';
defined('MOODLE_INTERNAL') || die();
$string['language'] = 'Idioma';
-$string['moodlelogo'] = 'Logotipo Moodle';
+$string['moodlelogo'] = 'Logótipo Moodle';
$string['next'] = 'Seguinte';
$string['previous'] = 'Anterior';
$string['reload'] = 'Recarregar';
<p>Trebuie să upgradați PHP sau să îl mutați pe o gazdă cu o nouă versiune de PHP!<br />
(În cazul 5.0.x puteți, de asemenea, să downgradați la versiunea 4.4.x)</p>';
$string['welcomep10'] = '{$a->installername} ({$a->installerversion})';
+$string['welcomep20'] = 'Vedeți această pagină deoarece ați instalat și lansat cu succes pachetul <strong>{$a->packname} {$a->packversion}</strong> în computerul dumneavoastră. Felicitări!';
$string['welcomep40'] = 'Pachetul include și <strong>Moodle {$a->moodlerelease} ({$a->moodleversion})</strong>.';
$string['wwwroot'] = 'Adresă Web';
$string['cliyesnoprompt'] = 'Введите y (обозначает Да) или n (обозначает Нет)';
$string['environmentrequireinstall'] = 'необходимо установить и включить';
$string['environmentrequireversion'] = 'требуется версия {$a->needed}, у Вас используется версия {$a->current}';
+$string['upgradekeyset'] = 'Ключ обновления (оставьте пустым, если не хотите его задавать)';
defined('MOODLE_INTERNAL') || die();
$string['language'] = 'Язык';
+$string['moodlelogo'] = 'Логотип Moodle';
$string['next'] = 'Далее';
$string['previous'] = 'Назад';
$string['reload'] = 'Обновить';
$string['pathsrodataroot'] = '資料根目錄是無法寫入的';
$string['pathsroparentdataroot'] = '上層目錄({$a->parent})是不可寫入的。安裝程式無法建立資料目錄({$a->dataroot})。';
$string['pathssubadmindir'] = '有些網站主機使用/admin這個網址來瀏覽控制面版或其他功能。很不幸,這個設定和Moodle管理頁面的標準路徑產生衝突。這個問題可以解決,只需在您的安裝目錄中把admin更換名稱,然後把新名稱輸入到這裡。例如<em>moodleadmin</em>這麼做會改變Moodle中的管理連接。';
-$string['pathssubdataroot'] = '你需要有一個地方讓Moodle可以儲存上傳的檔案。這一目錄對於網頁伺服器用戶(通常是"nobody"或"apache")而言,應該是可讀的和<b>可寫的</b>。但是它必須不能經由網頁直接存取。若此目錄不存在,這安裝程式將會試著建立它。';
+$string['pathssubdataroot'] = '<p>你需要有一個目錄讓Moodle可以儲存所有的用戶上傳的檔案。</p><p>這目錄對於網頁伺服器用戶(通常是"www-data"、"nobody"或"apache")而言,應該是可讀的和<b>可寫的</b>。</p>
+<p>它必須是不能透過網際網路直接存取的。</p>
+<p>若此目錄目前不存在,這安裝過程將會試著建立它。</p>';
$string['pathssubdirroot'] = '包含Moodle程式碼的目錄的完整路徑';
$string['pathssubwwwroot'] = '可以進入使用Moodle的完整網址,也就是用戶為了要使用Moodle,而需要輸入到瀏覽器的網址列的地址。
<p>您必須更新您的 PHP 或在有更新版本的主機上進行安裝!(若是5.0.x,你可以下降到4.4.x 版本)</p>';
$string['welcomep10'] = '{$a->installername} ({$a->installerversion})';
$string['welcomep20'] = '這個頁面是提醒您已經成功安裝與啟動 <strong>{$a->packname} {$a->packversion}</strong> ,恭喜!';
-$string['welcomep30'] = '<strong>{$a->installername}</strong>包含了可以建立<strong>Moodle</strong>執行環境的應用程序:';
+$string['welcomep30'] = '這一<strong>{$a->installername}</strong>的版本包含了一些可以建立<strong>Moodle</strong>執行環境的應用程序:';
$string['welcomep40'] = '這個軟體還包含了<strong>Moodle {$a->moodlerelease} ({$a->moodleversion})</strong>。';
$string['welcomep50'] = '使用本軟體包所包含的所有應用程序時,應遵循它們各自的授權協議。整個<strong>{$a->installername}</strong> 軟體都是<a href="http://www.opensource.org/docs/definition_plain.html">開放原始碼</a> ,並且是在 <a href="http://www.gnu.org/copyleft/gpl.html">GPL</a> 授權協議下發佈。';
-$string['welcomep60'] = '接下來的頁面將會透過一些簡單的步驟引導您安裝 <strong>Moodle</strong> 到電腦中,您可以接受預設值,或是針對自己的需求調整修改。';
+$string['welcomep60'] = '接下來的一些頁面將會透過一些簡單的步驟引導您配置和設定在你電腦上的 <strong>Moodle</strong> 。
+您可以接受這些預設值,或是針對你自己的需要來調整。';
$string['welcomep70'] = '點選 "下一步" 按鈕,繼續設定<strong>Moodle</strong>.';
$string['wwwroot'] = '網站位址';
$string['computedfromlogs'] = 'Computed from logs since {$a}.';
$string['condifmodeditdefaults'] = 'Default values are used in the settings form when creating a new activity or resource.';
$string['confeditorhidebuttons'] = 'Select the buttons that should be hidden in the HTML editor.';
+$string['configenableactivitychooser'] = 'The activity chooser is a dialog box with a short description of each activity and resource. If disabled, separate resource and activity dropdown menus are provided instead.';
$string['configallcountrycodes'] = 'This is the list of countries that may be selected in various places, for example in a user\'s profile. If blank (the default) the list in countries.php in the standard English language pack is used. That is the list from ISO 3166-1. Otherwise, you can specify a comma-separated list of codes, for example \'GB,FR,ES\'. If you add new, non-standard codes here, you will need to add them to countries.php in \'en\' and your language pack.';
$string['configallowassign'] = 'You can allow people who have the roles on the left side to assign some of the column roles to other people';
$string['configallowblockstodock'] = 'If enabled and supported by the selected theme users can choose to move blocks to a special dock.';
* Alternative text (optional) - String identifier and component of the alternative text of the emoticon.';
$string['emoticonsreset'] = 'Reset emoticons setting to default values';
$string['emptysettingvalue'] = 'Empty';
+$string['enableactivitychooser'] = 'Enable activity chooser';
$string['enableblogs'] = 'Enable blogs';
$string['enablecalendarexport'] = 'Enable calendar export';
$string['enablecomments'] = 'Enable comments';
$string['update_onupdate'] = 'On update';
$string['user_activatenotsupportusertype'] = 'auth: ldap user_activate() does not support selected usertype: {$a}';
$string['user_disablenotsupportusertype'] = 'auth: ldap user_disable() does not support selected usertype (..yet)';
+$string['username'] = 'Username';
+$string['username_help'] = 'Please be aware that some authentication plugins will not allow you to change the username.';
$string['backupversion'] = 'Backup version';
$string['cannotfindassignablerole'] = 'The {$a} role in the backup file cannot be mapped to any of the roles that you are allowed to assign.';
$string['choosefilefromcoursebackup'] = 'Course backup area';
-$string['choosefilefromcoursebackup_help'] = 'When backup courses using default settings, backup files will be stored here';
+$string['choosefilefromcoursebackup_help'] = 'Course backups made using default settings are stored here.';
$string['choosefilefromuserbackup'] = 'User private backup area';
-$string['choosefilefromuserbackup_help'] = 'When backup courses with "Anonymize user information" option ticked, backup files will be stored here';
+$string['choosefilefromuserbackup_help'] = 'Backup files with anonymized user information are stored here.';
$string['choosefilefromactivitybackup'] = 'Activity backup area';
-$string['choosefilefromactivitybackup_help'] = 'When backup activities using default settings, backup files will be stored here';
+$string['choosefilefromactivitybackup_help'] = 'Activity backups made using default settings are stored here.';
$string['choosefilefromautomatedbackup'] = 'Automated backups';
$string['choosefilefromautomatedbackup_help'] = 'Contains automatically generated backups.';
$string['configgeneralactivities'] = 'Sets the default for including activities in a backup.';
More details and the actual reason of the failure can be found in the restore log file.';
$string['filealiasesrestorefailures_link'] = 'restore/filealiases';
-$string['filereferencesincluded'] = 'File references to external contents included in backup package, they won\'t work on other sites.';
-$string['filereferencessamesite'] = 'Backup is from the same site, file references can be restored';
-$string['filereferencesnotsamesite'] = 'Backup is from other site, file references cannot be restored';
+$string['filereferencesincluded'] = 'File references to external contents are included in the backup file. These won\'t work if the backup is restored on a different site.';
+$string['filereferencessamesite'] = 'The backup file is from this site, and so file references can be restored.';
+$string['filereferencesnotsamesite'] = 'The backup file is from a different site, and so file references cannot be restored.';
$string['generalactivities'] = 'Include activities and resources';
$string['generalanonymize'] = 'Anonymise information';
$string['generalbackdefaults'] = 'General backup defaults';
$string['lockedbyhierarchy'] = 'Locked by dependencies';
$string['loglifetime'] = 'Keep logs for';
$string['managefiles'] = 'Manage backup files';
-$string['missingfilesinpool'] = 'Some files could not be saved during the backup, it won\'t be possible to restore them.';
+$string['missingfilesinpool'] = 'Some files could not be saved during the backup, and so it will not be possible to restore them.';
$string['moodleversion'] = 'Moodle version';
$string['moreresults'] = 'There are too many results, enter a more specific search.';
$string['nomatchingcourses'] = 'There are no courses to display';
$string['backpackemail'] = 'Email address';
$string['backpackemail_help'] = 'The email address associated with your backpack. While you are connected, any badges earned on this site will be associated with this email address.';
$string['personaconnection'] = 'Sign in with your email';
-$string['personaconnection_help'] = 'Persona is a system for identifying yourself across the web, using an email address that you own. The Open Badges backpack uses Persona as a login system, so to be able to connect to a backpack you with need a Persona account.
+$string['personaconnection_help'] = 'Persona is a system for identifying yourself across the web, using an email address that you own. The Open Badges backpack uses Persona as a login system, so to be able to connect to a backpack you will need a Persona account.
For more information about Persona visit <a href="https://login.persona.org/about">https://login.persona.org/about</a>.';
$string['backpackimport'] = 'Badge import settings';
settypeofficial,core_tag
filetoolarge,core
maxbytesforfile,core
+modchooserenable,core
+modchooserdisable,core
maxbytes,core_error
downloadcsv,core_table
downloadexcel,core_table
downloadods,core_table
downloadoptions,core_table
downloadtsv,core_table
-downloadxhtml,core_table
+downloadxhtml,core_table
\ No newline at end of file
$string['nativemariadb'] = 'MariaDB (native/mariadb)';
$string['nativemariadbhelp'] = '<p>The database is where most of the Moodle settings and data are stored and must be configured here.</p>
<p>The database name, username, and password are required fields; table prefix is optional.</p>
+<p>The database name may contain only alphanumeric characters, dollar ($) and underscore (_).</p>
<p>If the database currently does not exist, and the user you specify has permission, Moodle will attempt to create a new database with the correct permissions and settings.</p>
<p>This driver is not compatible with legacy MyISAM engine.</p>';
$string['nativemysqli'] = 'Improved MySQL (native/mysqli)';
$string['nativemysqlihelp'] = '<p>The database is where most of the Moodle settings and data are stored and must be configured here.</p>
<p>The database name, username, and password are required fields; table prefix is optional.</p>
+<p>The database name may contain only alphanumeric characters, dollar ($) and underscore (_).</p>
<p>If the database currently does not exist, and the user you specify has permission, Moodle will attempt to create a new database with the correct permissions and settings.</p>';
$string['nativemssql'] = 'SQL*Server FreeTDS (native/mssql)';
$string['nativemssqlhelp'] = 'Now you need to configure the database where most Moodle data will be stored.
$string['courseformatoptions'] = 'Formatting options for {$a}';
$string['courseformatudpate'] = 'Update format';
$string['courseprofiles'] = 'Course profiles';
+$string['coursepreferences'] = 'Course preferences';
$string['coursegrades'] = 'Course grades';
$string['coursehelpcategory'] = 'Position the course on the course listing and may make it easier for students to find it.';
$string['coursehelpforce'] = 'Force the course group mode to every activity in the course.';
$string['month'] = 'Month';
$string['months'] = 'Months';
$string['modified'] = 'Modified';
-$string['modchooserenable'] = 'Activity chooser on';
-$string['modchooserdisable'] = 'Activity chooser off';
$string['moduleintro'] = 'Description';
$string['modulesetup'] = 'Setting up module tables';
$string['modulesuccess'] = '{$a} tables have been set up correctly';
// Deprecated since Moodle 3.1.
$string['filetoolarge'] = 'is too large to upload';
$string['maxbytesforfile'] = 'The file {$a} is larger than the maximum size allowed.';
+
+// Deprecated since Moodle 3.2.
+$string['modchooserenable'] = 'Activity chooser on';
+$string['modchooserdisable'] = 'Activity chooser off';
\ No newline at end of file
$string['categorycurrentuse'] = 'Use this category';
$string['categorydoesnotexist'] = 'This category does not exist';
$string['categoryinfo'] = 'Category info';
-$string['categorymove'] = 'The category \'{$a->name}\' contains {$a->count} questions (some of them may be old, hidden, questions, or Random questions that are still in use in some existing quizzes). Please choose another category to move them to.';
+$string['categorymove'] = 'The category \'{$a->name}\' contains {$a->count} questions (some of which may be hidden questions or random questions that are still in use in a quiz). Please choose another category to move them to.';
$string['categorymoveto'] = 'Save in category';
$string['categorynamecantbeblank'] = 'The category name cannot be blank.';
$string['clickflag'] = 'Flag question';
* Make a series of ajax requests and return all the responses.
*
* @method call
- * @param {Object[]} Array of requests with each containing methodname and args properties.
+ * @param {Object[]} requests Array of requests with each containing methodname and args properties.
* done and fail callbacks can be set for each element in the array, or the
* can be attached to the promises returned by this function.
* @param {Boolean} async Optional, defaults to true.
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since 3.0
*/
-define([ 'jquery', 'core/yui' ],
+define(['jquery', 'core/yui'],
function($, Y) {
return /** @alias module:core/event */ {
* Trigger an event using both JQuery and YUI
*
* @method notifyFilterContentUpdated
- * @param {string}|{JQuery} nodes - Selector or list of elements that were inserted.
+ * @param {string|JQuery} nodes - Selector or list of elements that were inserted.
*/
notifyFilterContentUpdated: function(nodes) {
nodes = $(nodes);
* @since 2.9
*/
define(['jquery'], function($) {
- $(document).bind("ajaxStart", function(){
+ $(document).bind("ajaxStart", function() {
M.util.js_pending('jq');
- }).bind("ajaxStop", function(){
+ }).bind("ajaxStop", function() {
M.util.js_complete('jq');
});
});
}
originalSelect.children('option').each(function(index, ele) {
if ($(ele).prop('selected')) {
- items.push( { label: $(ele).html(), value: $(ele).attr('value') } );
+ items.push({ label: $(ele).html(), value: $(ele).attr('value') });
}
});
var context = $.extend({ items: items }, options, state);
* Notify of a change in the selection.
*
* @param {jQuery} originalSelect The jQuery object matching the hidden select list.
- * @return {Void}
*/
var notifyChange = function(originalSelect) {
if (typeof M.core_formchangechecker !== 'undefined') {
* @private
* @param {Object} options Original options for this autocomplete element.
* @param {Object} state State variables for this autocomplete element.
- * @param {Element} The item to be deselected.
+ * @param {Element} item The item to be deselected.
* @param {Element} originalSelect The original select list.
*/
var deselectItem = function(options, state, item, originalSelect) {
// Find it's index.
var current = suggestionsElement.children('[aria-hidden=false]').index(element);
// Activate the next one.
- activateItem(current+1, state);
+ activateItem(current + 1, state);
};
/**
// Find it's index.
var current = selectionsElement.children('[aria-selected=true]').index(element);
// Activate the next one.
- activateSelection(current-1, state);
+ activateSelection(current - 1, state);
};
/**
* Find the index of the current active selection, and activate the next one.
// Find it's index.
var current = selectionsElement.children('[aria-selected=true]').index(element);
// Activate the next one.
- activateSelection(current+1, state);
+ activateSelection(current + 1, state);
};
/**
// Find it's index.
var current = suggestionsElement.children('[aria-hidden=false]').index(element);
// Activate the next one.
- activateItem(current-1, state);
+ activateItem(current - 1, state);
};
/**
* Turn a boring select box into an auto-complete beast.
*
* @method enhance
- * @param {string} select The selector that identifies the select box.
+ * @param {string} selector The selector that identifies the select box.
* @param {boolean} tags Whether to allow support for tags (can define new entries).
* @param {string} ajax Name of an AMD module to handle ajax requests. If specified, the AMD
* module must expose 2 functions "transport" and "processResults".
* These are modeled on Select2 see: https://select2.github.io/options.html#ajax
* @param {String} placeholder - The text to display before a selection is made.
* @param {Boolean} caseSensitive - If search has to be made case sensitive.
+ * @param {Boolean} showSuggestions - If suggestions should be shown
* @param {String} noSelectionString - Text to display when there is no selection
*/
enhance: function(selector, tags, ajax, placeholder, caseSensitive, showSuggestions, noSelectionString) {
options.showSuggestions = showSuggestions;
}
if (typeof noSelectionString === "undefined") {
- str.get_string('noselection', 'form').done(function (result) {
+ str.get_string('noselection', 'form').done(function(result) {
options.noSelectionString = result;
}).fail(notification.exception);
}
var originalSelect = $(selector);
if (!originalSelect) {
log.debug('Selector not found: ' + selector);
- return false;
+ return;
}
// Hide the original select.
var promises = ajax.call([{
methodname: 'core_get_fragment',
- args:{
+ args: {
component: component,
callback: callback,
contextid: contextid,
// Disable cache if debugging.
return false;
}
- if (typeof(window.localStorage) === "undefined") {
+ if (typeof (window.localStorage) === "undefined") {
return false;
}
var testKey = 'test';
* Hash a string, used to make shorter key prefixes.
*
* @method hashString
- * @param string source The string to hash
- * @return int The int hash
+ * @param {String} source The string to hash
+ * @return {Number}
*/
var hashString = function(source) {
// From http://stackoverflow.com/questions/7616461/generate-a-hash-from-string-in-javascript-jquery.
return hash;
}
for (i = 0, len = source.length; i < len; i++) {
- chr = source.charCodeAt(i);
- hash = ((hash << 5) - hash) + chr;
+ chr = source.charCodeAt(i);
+ hash = ((hash << 5) - hash) + chr;
hash |= 0; // Convert to 32bit integer
}
return hash;
*/
define(['core/loglevel'], function(log) {
var originalFactory = log.methodFactory;
- log.methodFactory = function (methodName, logLevel) {
+ log.methodFactory = function(methodName, logLevel) {
var rawMethod = originalFactory(methodName, logLevel);
- return function (message, source) {
+ return function(message, source) {
if (source) {
rawMethod(source + ": " + message);
} else {
/**
* Set default config settings.
*
- * @param {String} level The level to use.
+ * @param {Object} config including the level to use.
* @method setConfig
*/
log.setConfig = function(config) {
if (notification.template) {
template = notification.template;
delete notification.template;
- } else if (notification.type){
+ } else if (notification.type) {
if (typeof notificationModule.types[notification.type] !== 'undefined') {
template = notificationModule.types[notification.type];
}
alert: function(title, message, yesLabel) {
// Here we are wrapping YUI. This allows us to start transitioning, but
// wait for a good alternative without having inconsistent dialogues.
- Y.use('moodle-core-notification-alert', function () {
+ Y.use('moodle-core-notification-alert', function() {
var alert = new M.core.alert({
- title : title,
- message : message,
+ title: title,
+ message: message,
yesLabel: yesLabel
});
confirm: function(title, question, yesLabel, noLabel, yesCallback, noCallback) {
// Here we are wrapping YUI. This allows us to start transitioning, but
// wait for a good alternative without having inconsistent dialogues.
- Y.use('moodle-core-notification-confirm', function () {
+ Y.use('moodle-core-notification-confirm', function() {
var modal = new M.core.confirm({
- title : title,
- question : question,
+ title: title,
+ question: question,
yesLabel: yesLabel,
noLabel: noLabel
});
ex.stack = ex.debuginfo;
ex.name = ex.errorcode;
}
- Y.use('moodle-core-notification-exception', function () {
+ Y.use('moodle-core-notification-exception', function() {
var modal = new M.core.exception(ex);
modal.show();
/**
* @module admin/permissionmanager
*/
-define(['jquery', 'core/config','core/notification', 'core/templates'], function($, config, notification, templates) {
+define(['jquery', 'core/config', 'core/notification', 'core/templates'], function($, config, notification, templates) {
/**
* Used CSS selectors
sesskey: config.sesskey
};
- $.post(adminurl + 'roles/ajax.php', params, function() {})
+ $.post(adminurl + 'roles/ajax.php', params)
.done(function(data) {
try {
overideableroles = data;
$('body').trigger(rolesloadedevent);
};
loadOverideableRoles();
- }
- catch(err) {
+ } catch (err) {
notification.exception(err);
}
})
*
* @access private
* @method changePermissions
- * @param {jquery node} row
+ * @param {JQuery} row
* @param {int} roleid
* @param {string} action
*/
action: action,
capability: row.data('name')
};
- $.post(adminurl + 'roles/ajax.php', params, function() {})
+ $.post(adminurl + 'roles/ajax.php', params)
.done(function(data) {
var action = data;
try {
default:
return;
}
- templates.render('core/permissionmanager_role',templatedata)
- .done(function (content) {
- if (action == 'allow'){
+ templates.render('core/permissionmanager_role', templatedata)
+ .done(function(content) {
+ if (action == 'allow') {
$(content).insertBefore(row.find('.allowmore:first'));
- }else if (action == 'prohibit'){
+ } else if (action == 'prohibit') {
$(content).insertBefore(row.find('.prohibitmore:first'));
// Remove allowed link
var allowedLink = row.find('.allowedroles').first().find('a[data-role-id="' + roleid + '"]');
panel.hide();
})
.fail(notification.exception);
- }
- catch(err) {
+ } catch (err) {
notification.exception(err);
}
})
* @method handleAddRole
* @param {event} e
*/
- var handleAddRole = function(e){
+ var handleAddRole = function(e) {
e.preventDefault();
$('body').one('rolesloaded', function() {
context: contextname
};
var message = M.util.get_string('role' + action + 'info', 'core_role', confirmationDetails);
- if (panel === null){
- panel = new M.core.dialogue ({
+ if (panel === null) {
+ panel = new M.core.dialogue({
draggable: true,
modal: true,
closeButton: true,
var i, existingrolelinks;
var roles = [];
- switch (action){
+ switch (action) {
case 'allow':
existingrolelinks = row.find(SELECTORS.REMOVEROLE);
break;
for (i in overideableroles) {
var disabled = '';
var disable = existingrolelinks.filter("[data-role-id='" + i + "']").length;
- if (disable){
+ if (disable) {
disabled = 'disabled';
}
- var roledetails = {roleid:i, rolename: overideableroles[i], disabled:disabled};
+ var roledetails = {roleid: i, rolename: overideableroles[i], disabled: disabled};
roles.push(roledetails);
}
- templates.render('core/permissionmanager_panelcontent',{message:message, roles:roles})
- .done(function (content) {
+ templates.render('core/permissionmanager_panelcontent', {message: message, roles: roles})
+ .done(function(content) {
panel.set('bodyContent', content);
panel.show();
- $('div.role_buttons').delegate('input', 'click',function(e){
+ $('div.role_buttons').delegate('input', 'click', function(e) {
var roleid = $(e.currentTarget).data('role-id');
changePermissions(row, roleid, action);
});
* @method handleRemoveRole
* @param {event} e
*/
- var handleRemoveRole = function(e){
+ var handleRemoveRole = function(e) {
e.preventDefault();
$('body').one('rolesloaded', function() {
var link = $(e.currentTarget);
};
notification.confirm(M.util.get_string('confirmunassigntitle', 'core_role'),
- M.util.get_string('confirmrole' + action, 'core_role',questionDetails),
+ M.util.get_string('confirmrole' + action, 'core_role', questionDetails),
M.util.get_string('confirmunassignyes', 'core_role'),
M.util.get_string('confirmunassignno', 'core_role'),
- function(){
+ function() {
changePermissions(row, roleid, action);
}
);
/**
* Initialize permissionmanager
* @access public
- * @param {int} contextid
- * @param {string} contextname
- * @param {string} adminurl
+ * @param {Object} args
*/
- initialize : function(args) {
+ initialize: function(args) {
contextid = args.contextid;
contextname = args.contextname;
adminurl = args.adminurl;
body.delegate(SELECTORS.REMOVEROLE, 'click', handleRemoveRole);
}
};
-});
\ No newline at end of file
+});
* @param {string} lang The users language - if not passed it is deduced.
* @return {Promise}
*/
+ // eslint-disable-next-line camelcase
get_string: function(key, component, param, lang) {
var request = this.get_strings([{
key: key,
* See get_string for more info on these args.
* @return {Promise}
*/
+ // eslint-disable-next-line camelcase
get_strings: function(requests) {
var deferred = $.Deferred();
// Click handler for changing tag type.
$('body').delegate('.tagarea[data-ta] a[data-quickload=1]', 'click', function(e) {
e.preventDefault();
- var target = $( this ),
+ var target = $(this),
query = target.context.search.replace(/^\?/, ''),
tagarea = target.closest('.tagarea[data-ta]'),
- args = query.split('&').reduce(function(s,c){var t=c.split('=');s[t[0]]=decodeURIComponent(t[1]);return s;},{});
+ args = query.split('&').reduce(function(s, c) {
+ var t = c.split('=');
+ s[t[0]] = decodeURIComponent(t[1]);
+ return s;
+ }, {});
var promises = ajax.call([{
methodname: 'core_tag_get_tagindex',
}], true);
$.when.apply($, promises)
- .done( function(data) {
+ .done(function(data) {
templates.render('core_tag/index', data).done(function(html) {
tagarea.replaceWith(html);
});
e.preventDefault();
var href = $(this).attr('href');
str.get_strings([
- {key : 'delete'},
- {key : 'confirmdeletetag', component : 'tag'},
- {key : 'yes'},
- {key : 'no'},
+ {key: 'delete'},
+ {key: 'confirmdeletetag', component: 'tag'},
+ {key: 'yes'},
+ {key: 'no'},
]).done(function(s) {
notification.confirm(s[0], s[1], s[2], s[3], function() {
window.location.href = href;
});
// Confirmation for bulk tag delete button.
- $("#tag-management-delete").click(function(e){
+ $("#tag-management-delete").click(function(e) {
var form = $(this).closest('form').get(0),
cnt = $(form).find("input[type=checkbox]:checked").length;
if (!cnt) {
var tempElement = $("<input type='hidden'/>").attr('name', this.name);
e.preventDefault();
str.get_strings([
- {key : 'delete'},
- {key : 'confirmdeletetags', component : 'tag'},
- {key : 'yes'},
- {key : 'no'},
+ {key: 'delete'},
+ {key: 'confirmdeletetags', component: 'tag'},
+ {key: 'yes'},
+ {key: 'no'},
]).done(function(s) {
notification.confirm(s[0], s[1], s[2], s[3], function() {
tempElement.appendTo(form);
});
// Confirmation for bulk tag combine button.
- $("#tag-management-combine").click(function(e){
+ $("#tag-management-combine").click(function(e) {
e.preventDefault();
var form = $(this).closest('form').get(0),
tags = $(form).find("input[type=checkbox]:checked");
if (tags.length <= 1) {
str.get_strings([
- {key : 'combineselected', component : 'tag'},
- {key : 'selectmultipletags', component : 'tag'},
- {key : 'ok'},
+ {key: 'combineselected', component: 'tag'},
+ {key: 'selectmultipletags', component: 'tag'},
+ {key: 'ok'},
]).done(function(s) {
notification.alert(s[0], s[1], s[2]);
}
}
var tempElement = $("<input type='hidden'/>").attr('name', this.name);
str.get_strings([
- {key : 'combineselected', component : 'tag'},
- {key : 'selectmaintag', component : 'tag'},
- {key : 'continue'},
- {key : 'cancel'},
+ {key: 'combineselected', component: 'tag'},
+ {key: 'selectmaintag', component: 'tag'},
+ {key: 'continue'},
+ {key: 'cancel'},
]).done(function(s) {
- var el = $('<div><form id="combinetags_form" class="form-inline">'+
+ var el = $('<div><form id="combinetags_form" class="form-inline">' +
'<p class="description"></p><p class="options"></p>' +
- '<p class="mdl-align"><input type="submit" id="combinetags_submit"/>'+
+ '<p class="mdl-align"><input type="submit" id="combinetags_submit"/>' +
'<input type="button" id="combinetags_cancel"/></p>' +
'</form></div>');
el.find('.description').html(s[1]);
var fldset = el.find('.options');
tags.each(function() {
var tagid = $(this).val(),
- tagname = $('.inplaceeditable[data-itemtype=tagname][data-itemid='+tagid+']').attr('data-value');
- fldset.append($('<input type="radio" name="maintag" id="combinetags_maintag_'+tagid+'" value="'+tagid+
- '"/><label for="combinetags_maintag_'+tagid+'">'+tagname+'</label><br>'));
+ tagname = $('.inplaceeditable[data-itemtype=tagname][data-itemid=' + tagid + ']').attr('data-value');
+ fldset.append($('<input type="radio" name="maintag" id="combinetags_maintag_' + tagid + '" value="' +
+ tagid + '"/><label for="combinetags_maintag_' + tagid + '">' + tagname + '</label><br>'));
});
- var panel = new M.core.dialogue ({
+ var panel = new M.core.dialogue({
draggable: true,
modal: true,
closeButton: true,
if (exception.errorcode === 'namesalreadybeeingused') {
e.preventDefault(); // This will prevent default error dialogue.
str.get_strings([
- {key : 'nameuseddocombine', component : 'tag'},
- {key : 'yes'},
- {key : 'cancel'},
+ {key: 'nameuseddocombine', component: 'tag'},
+ {key: 'yes'},
+ {key: 'cancel'},
]).done(function(s) {
notification.confirm(e.message, s[0], s[1], s[2], function() {
window.location.href = window.location.href + "&newname=" + encodeURIComponent(newvalue) +
$('body').on('click', 'a[data-action=addstandardtag]', function(e) {
e.preventDefault();
str.get_strings([
- {key : 'addotags', component : 'tag'},
- {key : 'inputstandardtags', component : 'tag'},
- {key : 'continue'},
- {key : 'cancel'},
+ {key: 'addotags', component: 'tag'},
+ {key: 'inputstandardtags', component: 'tag'},
+ {key: 'continue'},
+ {key: 'cancel'},
]).done(function(s) {
var el = $('<div><form id="addtags_form" class="form-inline" method="POST">' +
'<input type="hidden" name="action" value="addstandardtag"/>' +
el.find('#addtags_form').attr('action', window.location.href);
el.find('#addtags_submit').attr('value', s[2]);
el.find('#addtags_cancel').attr('value', s[3]);
- var panel = new M.core.dialogue ({
+ var panel = new M.core.dialogue({
draggable: true,
modal: true,
closeButton: true,
areaid, collid, isenabled;
if (ajaxreturn.component === 'core_tag' && ajaxreturn.itemtype === 'tagareaenable') {
areaid = $(this).attr('data-itemid');
- $(".tag-collections-table ul[data-collectionid] li[data-areaid="+areaid+"]").addClass('hidden');
+ $(".tag-collections-table ul[data-collectionid] li[data-areaid=" + areaid + "]").addClass('hidden');
isenabled = ajaxreturn.value;
if (isenabled === '1') {
$(this).closest('tr').removeClass('dimmed_text');
collid = $(this).closest('tr').find('[data-itemtype="tagareacollection"]').attr("data-value");
- $(".tag-collections-table ul[data-collectionid="+collid+"] li[data-areaid="+areaid+"]")
+ $(".tag-collections-table ul[data-collectionid=" + collid + "] li[data-areaid=" + areaid + "]")
.removeClass('hidden');
} else {
$(this).closest('tr').addClass('dimmed_text');
}
if (ajaxreturn.component === 'core_tag' && ajaxreturn.itemtype === 'tagareacollection') {
areaid = $(this).attr('data-itemid');
- $(".tag-collections-table ul[data-collectionid] li[data-areaid="+areaid+"]").addClass('hidden');
+ $(".tag-collections-table ul[data-collectionid] li[data-areaid=" + areaid + "]").addClass('hidden');
collid = $(this).attr('data-value');
isenabled = $(this).closest('tr').find('[data-itemtype="tagareaenable"]').attr("data-value");
if (isenabled === "1") {
- $(".tag-collections-table ul[data-collectionid="+collid+"] li[data-areaid="+areaid+"]")
+ $(".tag-collections-table ul[data-collectionid=" + collid + "] li[data-areaid=" + areaid + "]")
.removeClass('hidden');
}
}
e.preventDefault();
var href = $(this).attr('data-url') + '&sesskey=' + M.cfg.sesskey;
str.get_strings([
- {key : 'addtagcoll', component : 'tag'},
- {key : 'name'},
- {key : 'searchable', component : 'tag'},
- {key : 'create'},
- {key : 'cancel'},
+ {key: 'addtagcoll', component: 'tag'},
+ {key: 'name'},
+ {key: 'searchable', component: 'tag'},
+ {key: 'create'},
+ {key: 'cancel'},
]).done(function(s) {
- var el = $('<div><form id="addtagcoll_form" class="form-inline">'+
+ var el = $('<div><form id="addtagcoll_form" class="form-inline">' +
'<p><label for="addtagcoll_name"></label>: ' +
'<input id="addtagcoll_name" type="text"/></p>' +
'<p><label for="addtagcoll_searchable"></label>: ' +
'<input id="addtagcoll_searchable" type="checkbox" value="1" checked/></p>' +
- '<p class="mdl-align"><input type="submit" id="addtagcoll_submit"/>'+
+ '<p class="mdl-align"><input type="submit" id="addtagcoll_submit"/>' +
'<input type="button" id="addtagcoll_cancel"/></p>' +
'</form></div>');
el.find('label[for="addtagcoll_name"]').html(s[1]);
el.find('label[for="addtagcoll_searchable"]').html(s[2]);
el.find('#addtagcoll_submit').attr('value', s[3]);
el.find('#addtagcoll_cancel').attr('value', s[4]);
- var panel = new M.core.dialogue ({
+ var panel = new M.core.dialogue({
draggable: true,
modal: true,
closeButton: true,
e.preventDefault();
var href = $(this).attr('data-url') + '&sesskey=' + M.cfg.sesskey;
str.get_strings([
- {key : 'delete'},
- {key : 'suredeletecoll', component : 'tag', param : $(this).attr('data-collname') },
- {key : 'yes'},
- {key : 'no'},
+ {key: 'delete'},
+ {key: 'suredeletecoll', component: 'tag', param: $(this).attr('data-collname') },
+ {key: 'yes'},
+ {key: 'no'},
]).done(function(s) {
notification.confirm(s[0], s[1], s[2], s[3], function() {
window.location.href = href;
});
}
};
-});
\ No newline at end of file
+});
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since 2.9
*/
-define([ 'core/mustache',
+define(['core/mustache',
'jquery',
'core/ajax',
'core/str',
* @param {string} templateName - should consist of the component and the name of the template like this:
* core/menu (lib/templates/menu.mustache) or
* tool_bananas/yellow (admin/tool/bananas/templates/yellow.mustache)
+ * @param {Boolean} async If false - this function will not return until the promises are resolved.
* @return {Promise} JQuery promise object resolved when the template has been fetched.
*/
var getTemplate = function(templateName, async) {
// Oh well - load via ajax.
var promises = ajax.call([{
methodname: 'core_output_load_template',
- args:{
+ args: {
component: component,
template: name,
themename: currentThemeName
}], async, false);
promises[0].done(
- function (templateSource) {
+ function(templateSource) {
storage.set('core_template/' + searchKey, templateSource);
templateCache[searchKey] = templateSource;
deferred.resolve(templateSource);
}
).fail(
- function (ex) {
+ function(ex) {
deferred.reject(ex);
}
);
requiredStrings = [];
requiredJS = [];
context.uniqid = uniqid++;
- context.str = function() { return stringHelper; };
- context.pix = function() { return pixHelper; };
- context.js = function() { return jsHelper; };
- context.quote = function() { return quoteHelper; };
- context.globals = { config : config };
+ context.str = function() {
+ return stringHelper;
+ };
+ context.pix = function() {
+ return pixHelper;
+ };
+ context.js = function() {
+ return jsHelper;
+ };
+ context.quote = function() {
+ return quoteHelper;
+ };
+ context.globals = { config: config };
context.currentTheme = themeName;
};
*/
var runTemplateJS = function(source) {
if (source.trim() !== '') {
- var newscript = $('<script>').attr('type','text/javascript').html(source);
+ var newscript = $('<script>').attr('type', 'text/javascript').html(source);
$('head').append(newscript);
}
};
* Replace a node in the page with some new HTML and run the JS.
*
* @method replaceNodeContents
- * @param {string} source - A block of javascript.
+ * @param {JQuery} element - Element or selector to replace.
+ * @param {String} newHTML - HTML to insert / replace.
+ * @param {String} newJS - Javascript to run after the insertion.
*/
replaceNodeContents: function(element, newHTML, newJS) {
- return domReplace(element, newHTML, newJS, true);
+ domReplace(element, newHTML, newJS, true);
},
/**
* Insert a node in the page with some new HTML and run the JS.
*
* @method replaceNode
- * @param {string} source - A block of javascript.
+ * @param {JQuery} element - Element or selector to replace.
+ * @param {String} newHTML - HTML to insert / replace.
+ * @param {String} newJS - Javascript to run after the insertion.
*/
replaceNode: function(element, newHTML, newJS) {
- return domReplace(element, newHTML, newJS, false);
+ domReplace(element, newHTML, newJS, false);
}
};
});
* Get all visible tree items.
*
* @method getVisibleItems
+ * @return {Object} visible items
*/
Tree.prototype.getVisibleItems = function() {
return this.treeRoot.data('visibleItems');
* @method handleKeyDown
* @param {Object} item is the jquery id of the parent item of the group.
* @param {Event} e The event.
+ * @return {Boolean}
*/
Tree.prototype.handleKeyDown = function(item, e) {
var currentIndex = this.getVisibleItems().index(item);
* @method handleClick
* @param {Object} item The jquery id of the parent item of the group.
* @param {Event} e The event.
+ * @return {Boolean}
*/
Tree.prototype.handleClick = function(item, e) {
* @method handleFocus
* @param {Object} item The jquery id of the parent item of the group.
* @param {Event} e The event.
+ * @return {Boolean}
*/
Tree.prototype.handleFocus = function(item, e) {
// Bind event handlers to the tree items. Use event delegates to allow
// for dynamically loaded parts of the tree.
this.treeRoot.on({
- click: function(e) { return thisObj.handleClick($(this), e); },
- keydown: function(e) { return thisObj.handleKeyDown($(this), e); },
- focus: function(e) { return thisObj.handleFocus($(this), e); },
+ click: function(e) {
+ return thisObj.handleClick($(this), e);
+ },
+ keydown: function(e) {
+ return thisObj.handleKeyDown($(this), e);
+ },
+ focus: function(e) {
+ return thisObj.handleFocus($(this), e);
+ },
}, SELECTORS.ITEM);
};
return /** @alias module:core/url */ {
// Public variables and functions.
/**
- * Generate a style tag referencing this sheet and add it to the head of the page.
+ * Construct a file url
*
* @method fileUrl
- * @param {string} sheet The style sheet name. Must exist in the theme, or one of it's parents.
+ * @param {string} relativeScript
+ * @param {string} slashArg
* @return {string}
*/
fileUrl: function(relativeScript, slashArg) {
* - large: 2560x1600
*
* @param string $windowsize size of window.
+ * @param bool $viewport If true, changes viewport rather than window size
* @throws ExpectationException
*/
- protected function resize_window($windowsize) {
+ protected function resize_window($windowsize, $viewport = false) {
// Non JS don't support resize window.
if (!$this->running_javascript()) {
return;
$width = (int) $size[0];
$height = (int) $size[1];
}
+ if ($viewport) {
+ // When setting viewport size, we set it so that the document width will be exactly
+ // as specified, assuming that there is a vertical scrollbar. (In cases where there is
+ // no scrollbar it will be slightly wider. We presume this is rare and predictable.)
+ // The window inner height will be as specified, which means the available viewport will
+ // actually be smaller if there is a horizontal scrollbar. We assume that horizontal
+ // scrollbars are rare so this doesn't matter.
+ $offset = $this->getSession()->getDriver()->evaluateScript(
+ 'return (function() { var before = document.body.style.overflowY;' .
+ 'document.body.style.overflowY = "scroll";' .
+ 'var result = {};' .
+ 'result.x = window.outerWidth - document.body.offsetWidth;' .
+ 'result.y = window.outerHeight - window.innerHeight;' .
+ 'document.body.style.overflowY = before;' .
+ 'return result; })();');
+ $width += $offset['x'];
+ $height += $offset['y'];
+ }
+
$this->getSession()->getDriver()->resizeWindow($width, $height);
}
// Wait for all the possible AJAX requests that have been
// already triggered by selectOption() to be finished.
if ($this->running_javascript()) {
- // Trigger change event as this is needed by some drivers (Phantomjs). Don't do it for
- // Singleselect as this will cause multiple event fire and lead to race-around condition.
- $browser = \Moodle\BehatExtension\Driver\MoodleSelenium2Driver::getBrowser();
- if (!$singleselect && ($browser == 'phantomjs')) {
- $script = "Syn.trigger('change', {}, {{ELEMENT}})";
- try {
- $this->session->getDriver()->triggerSynScript($this->field->getXpath(), $script);
- } catch (Exception $e) {
- // No need to do anything if element has been removed by JS.
- // This is possible when inline editing element is used.
+ // Trigger change event and click on first skip link, as some OS/browsers (Phantomjs, Mac-FF),
+ // don't close select option field and trigger event.
+ if (!$singleselect) {
+ $dialoguexpath = "//div[contains(concat(' ', normalize-space(@class), ' '), ' moodle-dialogue-focused ')]";
+ if (!$node = $this->session->getDriver()->find($dialoguexpath)) {
+ $script = "Syn.trigger('change', {}, {{ELEMENT}})";
+ try {
+ $this->session->getDriver()->triggerSynScript($this->field->getXpath(), $script);
+ $this->session->getDriver()->click('//body//div[@class="skiplinks"]');
+ } catch (\Exception $e) {
+ return;
+ }
+ } else {
+ try {
+ $this->session->getDriver()->click($dialoguexpath);
+ } catch (\Exception $e) {
+ return;
+ }
}
}
$this->session->wait(behat_base::TIMEOUT * 1000, behat_base::PAGE_READY_JS);
}
}
+ /**
+ * Updates the provided users profile picture based upon the expected fields returned from the edit or edit_advanced forms.
+ *
+ * @param stdClass $usernew An object that contains some information about the user being updated
+ * @param array $filemanageroptions
+ * @return bool True if the user was updated, false if it stayed the same.
+ */
+ public static function update_picture(stdClass $usernew, $filemanageroptions = array()) {
+ global $CFG, $DB;
+ require_once("$CFG->libdir/gdlib.php");
+
+ $context = context_user::instance($usernew->id, MUST_EXIST);
+ $user = core_user::get_user($usernew->id, 'id, picture', MUST_EXIST);
+
+ $newpicture = $user->picture;
+ // Get file_storage to process files.
+ $fs = get_file_storage();
+ if (!empty($usernew->deletepicture)) {
+ // The user has chosen to delete the selected users picture.
+ $fs->delete_area_files($context->id, 'user', 'icon'); // Drop all images in area.
+ $newpicture = 0;
+
+ } else {
+ // Save newly uploaded file, this will avoid context mismatch for newly created users.
+ file_save_draft_area_files($usernew->imagefile, $context->id, 'user', 'newicon', 0, $filemanageroptions);
+ if (($iconfiles = $fs->get_area_files($context->id, 'user', 'newicon')) && count($iconfiles) == 2) {
+ // Get file which was uploaded in draft area.
+ foreach ($iconfiles as $file) {
+ if (!$file->is_directory()) {
+ break;
+ }
+ }
+ // Copy file to temporary location and the send it for processing icon.
+ if ($iconfile = $file->copy_content_to_temp()) {
+ // There is a new image that has been uploaded.
+ // Process the new image and set the user to make use of it.
+ // NOTE: Uploaded images always take over Gravatar.
+ $newpicture = (int)process_new_icon($context, 'user', 'icon', 0, $iconfile);
+ // Delete temporary file.
+ @unlink($iconfile);
+ // Remove uploaded file.
+ $fs->delete_area_files($context->id, 'user', 'newicon');
+ } else {
+ // Something went wrong while creating temp file.
+ // Remove uploaded file.
+ $fs->delete_area_files($context->id, 'user', 'newicon');
+ return false;
+ }
+ }
+ }
+
+ if ($newpicture != $user->picture) {
+ $DB->set_field('user', 'picture', $newpicture, array('id' => $user->id));
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+
+
/**
* Definition of user profile fields and the expected parameter type for data validation.
*
*/
public static function can_convert_documents() {
global $CFG;
+ $currentversion = 0;
+ $supportedversion = 0.7;
$unoconvbin = \escapeshellarg($CFG->pathtounoconv);
$command = "$unoconvbin --version";
exec($command, $output);
- preg_match('/([0-9]+\.[0-9]+)/', $output[0], $matches);
- $currentversion = (float)$matches[0];
- $supportedversion = 0.7;
- if ($currentversion < $supportedversion) {
- return false;
+ // If the command execution returned some output, then get the unoconv version.
+ if ($output) {
+ foreach ($output as $response) {
+ if (preg_match('/unoconv (\\d+\\.\\d+)/', $response, $matches)) {
+ $currentversion = (float)$matches[1];
+ }
+ }
+ if ($currentversion < $supportedversion) {
+ return false;
+ }
+ return true;
}
-
- return true;
+ return false;
}
/**
// Namespace for the form bits and bobs
M.form = M.form || {};
-/**
- * Stores a list of the dependencyManager for each form on the page.
- */
-M.form.dependencyManagers = {};
-
-/**
- * Initialises a manager for a forms dependencies.
- * This should happen once per form.
- */
-M.form.initFormDependencies = function(Y, formid, dependencies) {
-
- // If the dependencies isn't an array or object we don't want to
- // know about it
- if (!Y.Lang.isArray(dependencies) && !Y.Lang.isObject(dependencies)) {
- return false;
- }
-
- /**
- * Fixes an issue with YUI's processing method of form.elements property
- * in Internet Explorer.
- * http://yuilibrary.com/projects/yui3/ticket/2528030
- */
- Y.Node.ATTRS.elements = {
- getter: function() {
- return Y.all(new Y.Array(this._node.elements, 0, true));
- }
+if (typeof M.form.dependencyManager === 'undefined') {
+ var dependencyManager = function() {
+ dependencyManager.superclass.constructor.apply(this, arguments);
};
+ Y.extend(dependencyManager, Y.Base, {
+ _locks: null,
+ _hides: null,
+ _dirty: null,
+ _nameCollections: null,
+ _fileinputs: null,
- // Define the dependency manager if it hasn't already been defined.
- M.form.dependencyManager = M.form.dependencyManager || (function(){
- var dependencyManager = function(config) {
- dependencyManager.superclass.constructor.apply(this, arguments);
- };
- dependencyManager.prototype = {
- _form : null,
- _locks : [],
- _hides : [],
- _dirty : [],
- _nameCollections : null,
- _fileinputs : null,
- initializer : function(config) {
- var i = 0, nodeName;
- this._form = Y.one('#'+formid);
- for (i in dependencies) {
- var elements = this.elementsByName(i);
- if (elements.size() == 0) {
- continue;
- }
- elements.each(function(node){
- nodeName = node.get('nodeName').toUpperCase();
- if (nodeName == 'INPUT') {
- if (node.getAttribute('type').match(/^(button|submit|radio|checkbox)$/)) {
- node.on('click', this.updateEventDependencies, this);
- } else {
- node.on('blur', this.updateEventDependencies, this);
- }
- node.on('change', this.updateEventDependencies, this);
- } else if (nodeName == 'SELECT') {
- node.on('change', this.updateEventDependencies, this);
- } else {
+ initializer: function() {
+ // Setup initial values for complex properties.
+ this._locks = {};
+ this._hides = {};
+ this._dirty = {};
+
+ // Setup event handlers.
+ Y.Object.each(this.get('dependencies'), function(value, i) {
+ var elements = this.elementsByName(i);
+ elements.each(function(node) {
+ var nodeName = node.get('nodeName').toUpperCase();
+ if (nodeName == 'INPUT') {
+ if (node.getAttribute('type').match(/^(button|submit|radio|checkbox)$/)) {
node.on('click', this.updateEventDependencies, this);
+ } else {
node.on('blur', this.updateEventDependencies, this);
- node.on('change', this.updateEventDependencies, this);
}
- }, this);
- }
- this._form.get('elements').each(function(input){
- if (input.getAttribute('type')=='reset') {
- input.on('click', function(){
- this._form.reset();
- this.updateAllDependencies();
- }, this);
+ node.on('change', this.updateEventDependencies, this);
+ } else if (nodeName == 'SELECT') {
+ node.on('change', this.updateEventDependencies, this);
+ } else {
+ node.on('click', this.updateEventDependencies, this);
+ node.on('blur', this.updateEventDependencies, this);
+ node.on('change', this.updateEventDependencies, this);
}
}, this);
+ }, this);
- return this.updateAllDependencies();
- },
- /**
- * Initializes the mapping from element name to YUI NodeList
- */
- initElementsByName : function() {
- var names = [];
- // Collect element names
- for (var i in dependencies) {
- names[i] = new Y.NodeList();
- for (var condition in dependencies[i]) {
- for (var value in dependencies[i][condition]) {
- for (var ei in dependencies[i][condition][value]) {
- names[dependencies[i][condition][value][ei]] = new Y.NodeList();
- }
- }
- }
+ // Handle the reset button.
+ this.get('form').get('elements').each(function(input) {
+ if (input.getAttribute('type') == 'reset') {
+ input.on('click', function() {
+ this.get('form').reset();
+ this.updateAllDependencies();
+ }, this);
}
- // Locate elements for each name
- this._form.get('elements').each(function(node){
- var name = node.getAttribute('name');
- if (names[name]) {
- names[name].push(node);
+ }, this);
+
+ this.updateAllDependencies();
+ },
+
+ /**
+ * Initializes the mapping from element name to YUI NodeList
+ */
+ initElementsByName: function() {
+ var names = {};
+
+ // Collect element names.
+ Y.Object.each(this.get('dependencies'), function(conditions, i) {
+ names[i] = new Y.NodeList();
+ for (var condition in conditions) {
+ for (var value in conditions[condition]) {
+ for (var ei in conditions[condition][value]) {
+ names[conditions[condition][value][ei]] = new Y.NodeList();
+ }
}
- });
- this._nameCollections = names;
- },
- /**
- * Gets all elements in the form by their name and returns
- * a YUI NodeList
- *
- * @param {string} name The form element name.
- * @return {Y.NodeList}
- */
- elementsByName : function(name) {
- if (!this._nameCollections) {
- this.initElementsByName();
}
- if (!this._nameCollections[name]) {
- return new Y.NodeList();
- }
- return this._nameCollections[name];
- },
- /**
- * Checks the dependencies the form has an makes any changes to the
- * form that are required.
- *
- * Changes are made by functions title _dependency_{dependencytype}
- * and more can easily be introduced by defining further functions.
- *
- * @param {EventFacade | null} e The event, if any.
- * @param {string} name The form element name to check dependencies against.
- */
- checkDependencies : function(e, dependon) {
- var tohide = [],
- tolock = [],
- condition, value, lock, hide,
- checkfunction, result, elements;
- if (!dependencies[dependon]) {
- return true;
+ });
+
+ // Locate elements for each name.
+ this.get('form').get('elements').each(function(node) {
+ var name = node.getAttribute('name');
+ if (({}).hasOwnProperty.call(names, name)) {
+ names[name].push(node);
}
- elements = this.elementsByName(dependon);
- for (condition in dependencies[dependon]) {
- for (value in dependencies[dependon][condition]) {
- checkfunction = '_dependency_'+condition;
- if (Y.Lang.isFunction(this[checkfunction])) {
- result = this[checkfunction].apply(this, [elements, value, e]);
+ });
+ this._nameCollections = names;
+ },
+
+ /**
+ * Gets all elements in the form by their name and returns
+ * a YUI NodeList
+ *
+ * @param {String} name The form element name.
+ * @return {Y.NodeList}
+ */
+ elementsByName: function(name) {
+ if (!this._nameCollections) {
+ this.initElementsByName();
+ }
+ if (!({}).hasOwnProperty.call(this._nameCollections, name)) {
+ return new Y.NodeList();
+ }
+ return this._nameCollections[name];
+ },
+
+ /**
+ * Checks the dependencies the form has an makes any changes to the
+ * form that are required.
+ *
+ * Changes are made by functions title _dependency{Dependencytype}
+ * and more can easily be introduced by defining further functions.
+ *
+ * @param {EventFacade | null} e The event, if any.
+ * @param {String} dependon The form element name to check dependencies against.
+ * @return {Boolean}
+ */
+ checkDependencies: function(e, dependon) {
+ var dependencies = this.get('dependencies'),
+ tohide = {},
+ tolock = {},
+ condition, value, lock, hide,
+ checkfunction, result, elements;
+ if (!({}).hasOwnProperty.call(dependencies, dependon)) {
+ return true;
+ }
+ elements = this.elementsByName(dependon);
+ for (condition in dependencies[dependon]) {
+ for (value in dependencies[dependon][condition]) {
+ checkfunction = '_dependency' + condition[0].toUpperCase() + condition.slice(1);
+ if (Y.Lang.isFunction(this[checkfunction])) {
+ result = this[checkfunction].apply(this, [elements, value, e]);
+ } else {
+ result = this._dependencyDefault(elements, value, e);
+ }
+ lock = result.lock || false;
+ hide = result.hide || false;
+ for (var ei in dependencies[dependon][condition][value]) {
+ var eltolock = dependencies[dependon][condition][value][ei];
+ if (({}).hasOwnProperty.call(tohide, eltolock)) {
+ tohide[eltolock] = tohide[eltolock] || hide;
} else {
- result = this._dependency_default(elements, value, e);
+ tohide[eltolock] = hide;
}
- lock = result.lock || false;
- hide = result.hide || false;
- for (var ei in dependencies[dependon][condition][value]) {
- var eltolock = dependencies[dependon][condition][value][ei];
- tohide[eltolock] = tohide[eltolock] || hide;
+
+ if (({}).hasOwnProperty.call(tolock, eltolock)) {
tolock[eltolock] = tolock[eltolock] || lock;
+ } else {
+ tolock[eltolock] = lock;
}
}
}
- for (var el in tolock) {
- var needsupdate = false;
- if (tolock[el]) {
- this._locks[el] = this._locks[el] || [];
- if (!this._locks[el][dependon]) {
- this._locks[el][dependon] = true;
- needsupdate = true;
- }
- } else if (this._locks[el] && this._locks[el][dependon]) {
- delete this._locks[el][dependon];
+ }
+
+ for (var el in tolock) {
+ var needsupdate = false;
+ if (!({}).hasOwnProperty.call(this._locks, el)) {
+ this._locks[el] = {};
+ }
+ if (({}).hasOwnProperty.call(tolock, el) && tolock[el]) {
+ if (!({}).hasOwnProperty.call(this._locks[el], dependon) || this._locks[el][dependon]) {
+ this._locks[el][dependon] = true;
needsupdate = true;
}
- if (tohide[el]) {
- this._hides[el] = this._hides[el] || [];
- if (!this._hides[el][dependon]) {
- this._hides[el][dependon] = true;
- needsupdate = true;
- }
- } else if (this._hides[el] && this._hides[el][dependon]) {
- delete this._hides[el][dependon];
+ } else if (({}).hasOwnProperty.call(this._locks[el], dependon) && this._locks[el][dependon]) {
+ delete this._locks[el][dependon];
+ needsupdate = true;
+ }
+
+ if (!({}).hasOwnProperty.call(this._hides, el)) {
+ this._hides[el] = {};
+ }
+ if (({}).hasOwnProperty.call(tohide, el) && tohide[el]) {
+ if (!({}).hasOwnProperty.call(this._hides[el], dependon) || this._hides[el][dependon]) {
+ this._hides[el][dependon] = true;
needsupdate = true;
}
- if (needsupdate) {
- this._dirty[el] = true;
- }
+ } else if (({}).hasOwnProperty.call(this._hides[el], dependon) && this._hides[el][dependon]) {
+ delete this._hides[el][dependon];
+ needsupdate = true;
}
- return true;
- },
- /**
- * Update all dependencies in form
- */
- updateAllDependencies : function() {
- for (var el in dependencies) {
- this.checkDependencies(null, el);
+
+ if (needsupdate) {
+ this._dirty[el] = true;
}
- this.updateForm();
- },
- /**
- * Update dependencies associated with event
- *
- * @param {Event} e The event.
- */
- updateEventDependencies : function(e) {
- var el = e.target.getAttribute('name');
- this.checkDependencies(e, el);
- this.updateForm();
- },
- /**
- * Flush pending changes to the form
- */
- updateForm : function() {
- for (var el in this._dirty) {
- if (this._locks[el]) {
- var locked = !this._isObjectEmpty(this._locks[el]);
- this._disableElement(el, locked);
- }
- if (this._hides[el]) {
- var hidden = !this._isObjectEmpty(this._hides[el]);
- this._hideElement(el, hidden);
- }
+ }
+
+ return true;
+ },
+ /**
+ * Update all dependencies in form