diff --git a/admin/tool/lp/amd/build/scaleconfig.min.js b/admin/tool/lp/amd/build/scaleconfig.min.js new file mode 100644 index 00000000000..ae288b2a7c3 --- /dev/null +++ b/admin/tool/lp/amd/build/scaleconfig.min.js @@ -0,0 +1 @@ +define(["jquery","core/notification","core/templates","core/ajax","core/dialogue"],function(a,b,c,d,e){var f=null,g=0,h=0,i=function(){h=a("#id_scaleid").val();var d=a("#id_scaleid option:selected").text();m(h).done(function(){var a={scalename:d,scales:f};c.render("tool_lp/scale_configuration_page",a).done(function(a){new e(d,a,k)}).fail(b.exception)}).fail(b.exception)},j=function(){var b=a("#tool_lp_scaleconfiguration").val();if(""!==b){var c=a.parseJSON(b),d=c.shift();if(d.scaleid===g)return c}return""},k=function(b){var c=a(b.getContent());if(g===h){var d=j();""!==d&&d.forEach(function(b){1===b.scaledefault&&a("#tool_lp_scale_default_"+b.id).attr("checked",!0),1===b.proficient&&a("#tool_lp_scale_proficient_"+b.id).attr("checked",!0)})}c.on("click",'[data-action="close"]',function(){l(),b.close()}),c.on("click",'[data-action="cancel"]',function(){b.close()})},l=function(){var b=[{scaleid:h}];f.forEach(function(c){var d=0,e=0;a("#tool_lp_scale_default_"+c.id).is(":checked")&&(d=1),a("#tool_lp_scale_proficient_"+c.id).is(":checked")&&(e=1),b.push({name:c.name,id:c.id,scaledefault:d,proficient:e})});var c=JSON.stringify(b);a("#tool_lp_scaleconfiguration").val(c),g=h},m=function(b){var c=a.Deferred(),e=d.call([{methodname:"tool_lp_get_scale_values",args:{scaleid:b}}]);return e[0].done(function(a){f=a,c.resolve(a)}).fail(function(a){c.reject(a)}),c.promise()};return{init:function(){g=a("#id_scaleid").val(),a("#id_scaleconfigbutton").click(i)}}}); \ No newline at end of file diff --git a/admin/tool/lp/amd/src/scaleconfig.js b/admin/tool/lp/amd/src/scaleconfig.js new file mode 100644 index 00000000000..1dee9e2dd4d --- /dev/null +++ b/admin/tool/lp/amd/src/scaleconfig.js @@ -0,0 +1,171 @@ +// 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 . + +/** + * Handle opening a dialogue to configure scale data. + * + * @module tool_lp/scaleconfig + * @package tool_lp + * @copyright 2015 Adrian Greeve + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +define(['jquery', 'core/notification', 'core/templates', 'core/ajax', 'core/dialogue'], + function($, notification, templates, ajax, Dialogue) { + + /** @var {Array} scalevalues ID and name of the scales. */ + var scalevalues = null; + /** @var {Number) originalscaleid Original scale ID when the page loads. */ + var originalscaleid = 0; + /** @var {Number} scaleid Current scale ID. */ + var scaleid = 0; + + /** + * Displays the scale configuration dialogue. + * + * @method showConfig + */ + var showConfig = function() { + scaleid = $("#id_scaleid").val(); + var scalename = $("#id_scaleid option:selected").text(); + getScaleValues(scaleid).done(function() { + + var context = { + scalename: scalename, + scales: scalevalues + }; + + // Dish up the form. + templates.render('tool_lp/scale_configuration_page', context) + .done(function(html) { + new Dialogue( + scalename, + html, + initScaleConfig + ); + }).fail(notification.exception); + }).fail(notification.exception); + }; + + /** + * Gets the original scale configuration if it was set. + * + * @method retrieveOriginalScaleConfig + * @return {Object|String} scale configuration or empty string. + */ + var retrieveOriginalScaleConfig = function() { + var jsonstring = $('#tool_lp_scaleconfiguration').val(); + if (jsonstring !== '') { + var scaleconfiguration = $.parseJSON(jsonstring); + // The first object should contain the scale ID for the configuration. + var scaledetail = scaleconfiguration.shift(); + // Check that this scale id matches the one from the page before returning the configuration. + if (scaledetail.scaleid === originalscaleid) { + return scaleconfiguration; + } + } + return ''; + }; + + /** + * Initialises the scale configuration dialogue. + * + * @method initScaleConfig + * @param {Dialogue} popup Dialogue object to initialise. + */ + var initScaleConfig = function(popup) { + var body = $(popup.getContent()); + if (originalscaleid === scaleid) { + // Set up the popup to show the current configuration. + var currentconfig = retrieveOriginalScaleConfig(); + // Set up the form only if there is configuration settings to set. + if (currentconfig !== '') { + currentconfig.forEach(function(value) { + if (value.scaledefault === 1) { + $('#tool_lp_scale_default_' + value.id).attr('checked', true); + } + if (value.proficient === 1) { + $('#tool_lp_scale_proficient_' + value.id).attr('checked', true); + } + }); + } + } + body.on('click', '[data-action="close"]', function() { setScaleConfig(); popup.close(); }); + body.on('click', '[data-action="cancel"]', function() { popup.close(); }); + }; + + /** + * Set the scale configuration back into a JSON string in the hidden element. + * + * @method setScaleConfig + */ + var setScaleConfig = function() { + // Get the data. + var data = [{ scaleid: scaleid}]; + scalevalues.forEach(function(value) { + var scaledefault = 0; + var proficient = 0; + if ($('#tool_lp_scale_default_' + value.id).is(':checked')) { scaledefault = 1; } + if ($('#tool_lp_scale_proficient_' + value.id).is(':checked')) { proficient = 1; } + data.push({ + name: value.name, + id: value.id, + scaledefault: scaledefault, + proficient: proficient + }); + }); + var datastring = JSON.stringify(data); + // Send to the hidden field on the form. + $('#tool_lp_scaleconfiguration').val(datastring); + // Once the configuration has been saved then the original scale ID is set to the current scale ID. + originalscaleid = scaleid; + }; + + /** + * Get the scale values for the selected scale. + * + * @method getScaleValues + * @param {Number} scaleid The scale ID of the selected scale. + * @return {Promise} A deffered object with the scale values. + */ + var getScaleValues = function(scaleid) { + var deferred = $.Deferred(); + var promises = ajax.call([{ + methodname: 'tool_lp_get_scale_values', + args: { + scaleid: scaleid + } + }]); + promises[0].done(function(result) { + scalevalues = result; + deferred.resolve(result); + }).fail(function(exception) { + deferred.reject(exception); + }); + return deferred.promise(); + }; + + return { + /** + * Main initialisation. + * + * @method init + */ + init: function() { + // Get the current scale ID. + originalscaleid = $("#id_scaleid").val(); + $('#id_scaleconfigbutton').click(showConfig); + } + }; +}); \ No newline at end of file diff --git a/admin/tool/lp/classes/competency_framework.php b/admin/tool/lp/classes/competency_framework.php index a4f3eb85504..759bf685441 100644 --- a/admin/tool/lp/classes/competency_framework.php +++ b/admin/tool/lp/classes/competency_framework.php @@ -51,6 +51,12 @@ class competency_framework extends persistent { /** @var bool $visible Used to show/hide this framework */ private $visible = true; + /** @var int $scaleid The scale ID for this framework */ + private $scaleid = 0; + + /** @var string $scaleconfiguration scale information relevant to this framework*/ + private $scaleconfiguration = ''; + /** * Method that provides the table name matching this class. * @@ -167,6 +173,42 @@ class competency_framework extends persistent { $this->visible = $visible; } + /** + * Get the scale ID. + * + * @return int The scale ID + */ + public function get_scaleid() { + return $this->scaleid; + } + + /** + * Set the scale ID. + * + * @param int $scale The scale ID + */ + public function set_scaleid($scaleid) { + $this->scaleid = $scaleid; + } + + /** + * Get the scale configuration. + * + * @return string The scale configuration + */ + public function get_scaleconfiguration() { + return $this->scaleconfiguration; + } + + /** + * Set the scale configuration. + * + * @param string $scaleconfiguration The scale configuration (JSON string) + */ + public function set_scaleconfiguration($scaleconfiguration) { + $this->scaleconfiguration = $scaleconfiguration; + } + /** * Populate this class with data from a DB record. * @@ -192,6 +234,12 @@ class competency_framework extends persistent { if (isset($record->sortorder)) { $this->set_sortorder($record->sortorder); } + if (isset($record->scaleid)) { + $this->set_scaleid($record->scaleid); + } + if (isset($record->scaleconfiguration)) { + $this->set_scaleconfiguration($record->scaleconfiguration); + } if (isset($record->visible)) { $this->set_visible($record->visible); } @@ -221,6 +269,8 @@ class competency_framework extends persistent { $record->descriptionformat = $this->get_descriptionformat(); $record->descriptionformatted = format_text($this->get_description(), $this->get_descriptionformat()); $record->sortorder = $this->get_sortorder(); + $record->scaleid = $this->get_scaleid(); + $record->scaleconfiguration = $this->get_scaleconfiguration(); $record->visible = $this->get_visible(); $record->timecreated = $this->get_timecreated(); $record->timemodified = $this->get_timemodified(); diff --git a/admin/tool/lp/classes/external.php b/admin/tool/lp/classes/external.php index ef0c396aea1..ccca11fc32d 100644 --- a/admin/tool/lp/classes/external.php +++ b/admin/tool/lp/classes/external.php @@ -24,6 +24,7 @@ namespace tool_lp; require_once("$CFG->libdir/externallib.php"); +require_once("$CFG->libdir/grade/grade_scale.php"); use external_api; use external_function_parameters; @@ -32,6 +33,7 @@ use external_format_value; use external_single_structure; use external_multiple_structure; use invalid_parameter_exception; +use grade_scale; /** * This is the external API for this tool. @@ -3451,4 +3453,70 @@ class external extends external_api { )); } + /** + * Returns the description of the get_scale_values() parameters. + * + * @return external_function_parameters. + */ + public static function get_scale_values_parameters() { + $scaleid = new external_value( + PARAM_INT, + 'The scale id', + VALUE_REQUIRED + ); + $params = array('scaleid' => $scaleid); + return new external_function_parameters($params); + } + + /** + * Expose to AJAX + * + * @return boolean + */ + public static function get_scale_values_is_allowed_from_ajax() { + return true; + } + + /** + * Get the values associated with a scale. + * + * @param int $scaleid Scale ID + * @return array Values for a scale. + */ + public static function get_scale_values($scaleid) { + global $DB; + $params = self::validate_parameters(self::get_scale_values_parameters(), + array( + 'scaleid' => $scaleid, + ) + ); + // The following section is not learning plan specific and so has not been moved to the api. + // Retrieve the scale value from the database. + $scale = grade_scale::fetch(array('id' => $scaleid)); + // Reverse the array so that high levels are at the top. + $scalevalues = array_reverse($scale->load_items()); + foreach ($scalevalues as $key => $value) { + // Add a key (make the first value 1). + $scalevalues[$key] = array( + 'id' => $key + 1, + 'name' => $value + ); + } + return $scalevalues; + } + + /** + * Returns description of get_scale_values() result value. + * + * @return external_description + */ + public static function get_scale_values_returns() { + return new external_multiple_structure( + new external_single_structure(array( + 'id' => new external_value(PARAM_INT, 'Scale value ID'), + 'name' => new external_value(PARAM_RAW, 'Scale value name') + ) + ) + ); + } } diff --git a/admin/tool/lp/classes/form/competency_framework.php b/admin/tool/lp/classes/form/competency_framework.php index 203ae2708c2..9cb34080908 100644 --- a/admin/tool/lp/classes/form/competency_framework.php +++ b/admin/tool/lp/classes/form/competency_framework.php @@ -44,6 +44,8 @@ class competency_framework extends moodleform { * Define the form - called by parent constructor */ public function definition() { + global $PAGE; + $mform = $this->_form; $id = $this->_customdata; @@ -61,6 +63,18 @@ class competency_framework extends moodleform { $mform->addElement('text', 'idnumber', get_string('idnumber', 'tool_lp')); $mform->setType('idnumber', PARAM_TEXT); + + $scales = get_scales_menu(); + $mform->addElement('select', 'scaleid', get_string('scale', 'tool_lp'), $scales); + $mform->setType('scaleid', PARAM_INT); + $mform->addHelpButton('scaleid', 'scale', 'tool_lp'); + + $mform->addElement('button', 'scaleconfigbutton', get_string('configurescale', 'tool_lp')); + // Add js. + $PAGE->requires->js_call_amd('tool_lp/scaleconfig', 'init'); + $mform->addElement('hidden', 'scaleconfiguration', '', array('id' => 'tool_lp_scaleconfiguration')); + $mform->setType('scaleconfiguration', PARAM_RAW); + $mform->addElement('selectyesno', 'visible', get_string('visible', 'tool_lp')); $mform->setDefault('visible', true); diff --git a/admin/tool/lp/db/install.xml b/admin/tool/lp/db/install.xml index 10039de3a51..0805e6e93b9 100755 --- a/admin/tool/lp/db/install.xml +++ b/admin/tool/lp/db/install.xml @@ -32,6 +32,8 @@ + + @@ -114,4 +116,4 @@ - \ No newline at end of file + diff --git a/admin/tool/lp/db/services.php b/admin/tool/lp/db/services.php index 7395d63d5eb..64915f30721 100644 --- a/admin/tool/lp/db/services.php +++ b/admin/tool/lp/db/services.php @@ -387,6 +387,14 @@ $functions = array( 'description' => 'Load the data for the plans page template', 'type' => 'read', 'capabilities'=> 'tool/lp:planviewown', + ), + 'tool_lp_get_scale_values' => array( + 'classname' => 'tool_lp\external', + 'methodname' => 'get_scale_values', + 'classpath' => '', + 'description' => 'Fetch the values for a specific scale', + 'type' => 'read', + 'capabilities'=> 'tool/lp:competencymanage', ) ); diff --git a/admin/tool/lp/lang/en/tool_lp.php b/admin/tool/lp/lang/en/tool_lp.php index befbf78a281..6cbb040954d 100644 --- a/admin/tool/lp/lang/en/tool_lp.php +++ b/admin/tool/lp/lang/en/tool_lp.php @@ -39,12 +39,14 @@ $string['lp:templateread'] = 'View template'; $string['competencies'] = 'Competencies'; $string['competenciesforframework'] = 'Competencies for {$a}'; $string['competencyframeworks'] = 'Competency Frameworks'; +$string['configurescale'] = 'Configure scales'; $string['addnewcompetencyframework'] = 'Add new competency framework'; $string['addnewplan'] = 'Add new learning plan'; $string['addnewtemplate'] = 'Add new learning plan template'; $string['addnewcompetency'] = 'Add new competency'; $string['addnewplan'] = 'Add new learning plan'; $string['addcompetency'] = 'Add competency'; +$string['default'] = 'Default'; $string['editcompetencyframework'] = 'Edit competency framework'; $string['erroreditingmodifiedplan'] = 'You can not edit a learning plan modified by another user if you don\'t have tool/lp:planmanage or tool/lp:planmanageown capabilities.'; $string['errorplanstatus'] = 'Learning plans {$a} status unknown'; @@ -60,8 +62,13 @@ $string['nocompetencies'] = 'No competencies have been created in this framework $string['nocompetenciesincourse'] = 'No competencies have been linked to this course.'; $string['nouserplans'] = 'No learning plans have been created yet.'; $string['nocompetenciesintemplate'] = 'No competencies have been linked to this template.'; +$string['proficient'] = 'Proficient'; + $string['shortname'] = 'Name'; $string['savechanges'] = 'Save changes'; +$string['scale'] = 'Scale'; +$string['scalevalue'] = 'Scale value'; +$string['scale_help'] = 'A scale determines how proficiency is measured in a competency. After selecting a scale, configure the scale, setting one of the scale values as default and marking all scale values that are deemed proficient.'; $string['description'] = 'Description'; $string['visible'] = 'Visible'; $string['visible_help'] = 'A competency framework can be hidden from teachers. This could be useful if a framework is still in the process of being developed.'; diff --git a/admin/tool/lp/templates/scale_configuration_page.mustache b/admin/tool/lp/templates/scale_configuration_page.mustache new file mode 100644 index 00000000000..650a0131ba4 --- /dev/null +++ b/admin/tool/lp/templates/scale_configuration_page.mustache @@ -0,0 +1,61 @@ +{{! + 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 . +}} +{{! + Set scale configuration for the competency framework. + + Classes required for JS: + * none + + Data attibutes required for JS: + * none + + Context variables required for this template: + * scales Array of id / name pairs. + + Example context (json): + { + "scales": [ + { "id": 1, "name": "Competent" }, + { "id": 2, "name": "Not competent"} + ] + } + }} +
+ + + + + + + + + + {{#scales}} + + + + + + {{/scales}} + +
{{#str}}scalevalue, tool_lp{{/str}}{{#str}}default, tool_lp{{/str}}{{#str}}proficient, tool_lp{{/str}}
{{name}}
+
+ +
+ + +
\ No newline at end of file diff --git a/admin/tool/lp/tests/externallib_test.php b/admin/tool/lp/tests/externallib_test.php index fcdf3cf9d23..a1b4118c2c4 100644 --- a/admin/tool/lp/tests/externallib_test.php +++ b/admin/tool/lp/tests/externallib_test.php @@ -886,4 +886,42 @@ class tool_lp_external_testcase extends externallib_advanced_testcase { $this->setUser($this->user); external::reorder_template_competency($template->id, $competency1->id, $competency2->id); } + + /** + * Test that we can return scale values for a scale with the scale ID. + */ + public function test_get_scale_values() { + global $DB; + // Create a scale. + $record = new stdClass(); + $record->courseid = 0; + $record->userid = $this->creator->id; + $record->name = 'Test scale'; + $record->scale = 'Poor, Not good, Okay, Fine, Excellent'; + $record->description = '

Test scale description.

'; + $record->descriptionformat = 1; + $record->timemodified = time(); + $scaleid = $DB->insert_record('scale', $record); + // Expected return value. + $expected = array(array( + 'id' => 1, + 'name' => 'Excellent' + ), array( + 'id' => 2, + 'name' => 'Fine' + ), array( + 'id' => 3, + 'name' => 'Okay' + ), array( + 'id' => 4, + 'name' => 'Not good' + ), array( + 'id' => 5, + 'name' => 'Poor' + ) + ); + // Call the webservice. + $result = external::get_scale_values($scaleid); + $this->assertEquals($expected, $result); + } }