From 5bbb99f9b734d8a2478e316c33ac215b79204e1d Mon Sep 17 00:00:00 2001 From: Frederic Massart Date: Thu, 10 Mar 2016 16:16:22 +0800 Subject: [PATCH] MDL-53421 tool_lp: Allow multiple instances of scale config on page --- admin/tool/lp/amd/build/scaleconfig.min.js | 2 +- admin/tool/lp/amd/src/scaleconfig.js | 116 ++++++++++++------ admin/tool/lp/classes/form/competency.php | 3 +- .../lp/classes/form/competency_framework.php | 3 +- .../scale_configuration_page.mustache | 6 +- 5 files changed, 86 insertions(+), 44 deletions(-) diff --git a/admin/tool/lp/amd/build/scaleconfig.min.js b/admin/tool/lp/amd/build/scaleconfig.min.js index acc8bdc9f0d..db0ffd838e6 100644 --- a/admin/tool/lp/amd/build/scaleconfig.min.js +++ b/admin/tool/lp/amd/build/scaleconfig.min.js @@ -1 +1 @@ -define(["jquery","core/notification","core/templates","core/ajax","tool_lp/dialogue","tool_lp/scalevalues"],function(a,b,c,d,e,f){var g=null,h=0,i=0,j=function(){if(i=a("#id_scaleid").val(),!(0>=i)){var d=a("#id_scaleid option:selected").text();n(i).done(function(){var a={scalename:d,scales:g};c.render("tool_lp/scale_configuration_page",a).done(function(a){new e(d,a,l)}).fail(b.exception)}).fail(b.exception)}},k=function(){var b=a("#tool_lp_scaleconfiguration").val();if(""!==b){var c=a.parseJSON(b),d=c.shift();if(d.scaleid===h)return c}return""},l=function(b){var c=a(b.getContent());if(h===i){var d=k();""!==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(){m(),b.close()}),c.on("click",'[data-action="cancel"]',function(){b.close()})},m=function(){var b=[{scaleid:i}];g.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),(d||e)&&b.push({id:c.id,scaledefault:d,proficient:e})});var c=JSON.stringify(b);a("#tool_lp_scaleconfiguration").val(c),h=i},n=function(a){return f.get_values(a).then(function(a){return g=a,a})},o=function(b){a(b.target).val()<=0?a("#id_scaleconfigbutton").prop("disabled",!0):a("#id_scaleconfigbutton").prop("disabled",!1)};return{init:function(){h=a("#id_scaleid").val(),a("#id_scaleid").on("change",o).change(),a("#id_scaleconfigbutton").click(j)}}}); \ No newline at end of file +define(["jquery","core/notification","core/templates","core/ajax","tool_lp/dialogue","tool_lp/scalevalues"],function(a,b,c,d,e,f){var g=function(b,c,d){this.selectSelector=b,this.inputSelector=c,this.triggerSelector=d,this.originalscaleid=a(b).val(),a(b).on("change",this.scaleChangeHandler.bind(this)).change(),a(d).click(this.showConfig.bind(this))};return g.prototype.selectSelector=null,g.prototype.inputSelector=null,g.prototype.triggerSelector=null,g.prototype.scalevalues=null,g.prototype.originalscaleid=0,g.prototype.scaleid=0,g.prototype.popup=null,g.prototype.showConfig=function(){var d=this;if(this.scaleid=a(this.selectSelector).val(),!(this.scaleid<=0)){var f=a(this.selectSelector).find("option:selected").text();this.getScaleValues(this.scaleid).done(function(){var a={scalename:f,scales:d.scalevalues};c.render("tool_lp/scale_configuration_page",a).done(function(a){new e(f,a,d.initScaleConfig.bind(d))}).fail(b.exception)}).fail(b.exception)}},g.prototype.retrieveOriginalScaleConfig=function(){var b=a(this.inputSelector).val();if(""!==b){var c=a.parseJSON(b),d=c.shift();if(d.scaleid===this.originalscaleid)return c}return""},g.prototype.initScaleConfig=function(b){this.popup=b;var c=a(b.getContent());if(this.originalscaleid===this.scaleid){var d=this.retrieveOriginalScaleConfig();""!==d&&d.forEach(function(a){1===a.scaledefault&&c.find('[data-field="tool_lp_scale_default_'+a.id+'"]').attr("checked",!0),1===a.proficient&&c.find('[data-field="tool_lp_scale_proficient_'+a.id+'"]').attr("checked",!0)})}c.on("click",'[data-action="close"]',function(){this.setScaleConfig(),b.close()}.bind(this)),c.on("click",'[data-action="cancel"]',function(){b.close()}.bind(this))},g.prototype.setScaleConfig=function(){var b=a(this.popup.getContent()),c=[{scaleid:this.scaleid}];this.scalevalues.forEach(function(a){var d=0,e=0;b.find('[data-field="tool_lp_scale_default_'+a.id+'"]').is(":checked")&&(d=1),b.find('[data-field="tool_lp_scale_proficient_'+a.id+'"]').is(":checked")&&(e=1),(d||e)&&c.push({id:a.id,scaledefault:d,proficient:e})});var d=JSON.stringify(c);a(this.inputSelector).val(d),this.originalscaleid=this.scaleid},g.prototype.getScaleValues=function(a){return f.get_values(a).then(function(a){return this.scalevalues=a,a}.bind(this))},g.prototype.scaleChangeHandler=function(b){a(b.target).val()<=0?a(this.triggerSelector).prop("disabled",!0):a(this.triggerSelector).prop("disabled",!1)},{init:function(a,b,c){return new g(a,b,c)}}}); \ No newline at end of file diff --git a/admin/tool/lp/amd/src/scaleconfig.js b/admin/tool/lp/amd/src/scaleconfig.js index ce0e96db438..11c8568fa00 100644 --- a/admin/tool/lp/amd/src/scaleconfig.js +++ b/admin/tool/lp/amd/src/scaleconfig.js @@ -24,31 +24,58 @@ define(['jquery', 'core/notification', 'core/templates', 'core/ajax', 'tool_lp/dialogue', 'tool_lp/scalevalues'], function($, notification, templates, ajax, Dialogue, ModScaleValues) { + /** + * Scale config object. + * @param {String} selectSelector The select box selector. + * @param {String} inputSelector The hidden input field selector. + * @param {String} triggerSelector The trigger selector. + */ + var ScaleConfig = function(selectSelector, inputSelector, triggerSelector) { + this.selectSelector = selectSelector; + this.inputSelector = inputSelector; + this.triggerSelector = triggerSelector; + + // Get the current scale ID. + this.originalscaleid = $(selectSelector).val(); + $(selectSelector).on('change', this.scaleChangeHandler.bind(this)).change(); + $(triggerSelector).click(this.showConfig.bind(this)); + }; + + /** @var {String} The select box selector. */ + ScaleConfig.prototype.selectSelector = null; + /** @var {String} The hidden field selector. */ + ScaleConfig.prototype.inputSelector = null; + /** @var {String} The trigger selector. */ + ScaleConfig.prototype.triggerSelector = null; /** @var {Array} scalevalues ID and name of the scales. */ - var scalevalues = null; + ScaleConfig.prototype.scalevalues = null; /** @var {Number) originalscaleid Original scale ID when the page loads. */ - var originalscaleid = 0; + ScaleConfig.prototype.originalscaleid = 0; /** @var {Number} scaleid Current scale ID. */ - var scaleid = 0; + ScaleConfig.prototype.scaleid = 0; + /** @var {Dialogue} Reference to the popup. */ + ScaleConfig.prototype.popup = null; /** * Displays the scale configuration dialogue. * * @method showConfig */ - var showConfig = function() { - scaleid = $("#id_scaleid").val(); - if (scaleid <= 0) { + ScaleConfig.prototype.showConfig = function() { + var self = this; + + this.scaleid = $(this.selectSelector).val(); + if (this.scaleid <= 0) { // This should not happen. return; } - var scalename = $("#id_scaleid option:selected").text(); - getScaleValues(scaleid).done(function() { + var scalename = $(this.selectSelector).find("option:selected").text(); + this.getScaleValues(this.scaleid).done(function() { var context = { scalename: scalename, - scales: scalevalues + scales: self.scalevalues }; // Dish up the form. @@ -57,7 +84,7 @@ define(['jquery', 'core/notification', 'core/templates', 'core/ajax', 'tool_lp/d new Dialogue( scalename, html, - initScaleConfig + self.initScaleConfig.bind(self) ); }).fail(notification.exception); }).fail(notification.exception); @@ -69,14 +96,14 @@ define(['jquery', 'core/notification', 'core/templates', 'core/ajax', 'tool_lp/d * @method retrieveOriginalScaleConfig * @return {Object|String} scale configuration or empty string. */ - var retrieveOriginalScaleConfig = function() { - var jsonstring = $('#tool_lp_scaleconfiguration').val(); + ScaleConfig.prototype.retrieveOriginalScaleConfig = function() { + var jsonstring = $(this.inputSelector).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) { + if (scaledetail.scaleid === this.originalscaleid) { return scaleconfiguration; } } @@ -89,25 +116,31 @@ define(['jquery', 'core/notification', 'core/templates', 'core/ajax', 'tool_lp/d * @method initScaleConfig * @param {Dialogue} popup Dialogue object to initialise. */ - var initScaleConfig = function(popup) { + ScaleConfig.prototype.initScaleConfig = function(popup) { + this.popup = popup; var body = $(popup.getContent()); - if (originalscaleid === scaleid) { + if (this.originalscaleid === this.scaleid) { // Set up the popup to show the current configuration. - var currentconfig = retrieveOriginalScaleConfig(); + var currentconfig = this.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); + body.find('[data-field="tool_lp_scale_default_' + value.id + '"]').attr('checked', true); } if (value.proficient === 1) { - $('#tool_lp_scale_proficient_' + value.id).attr('checked', true); + body.find('[data-field="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(); }); + body.on('click', '[data-action="close"]', function() { + this.setScaleConfig(); + popup.close(); + }.bind(this)); + body.on('click', '[data-action="cancel"]', function() { + popup.close(); + }.bind(this)); }; /** @@ -115,14 +148,19 @@ define(['jquery', 'core/notification', 'core/templates', 'core/ajax', 'tool_lp/d * * @method setScaleConfig */ - var setScaleConfig = function() { + ScaleConfig.prototype.setScaleConfig = function() { + var body = $(this.popup.getContent()); // Get the data. - var data = [{ scaleid: scaleid}]; - scalevalues.forEach(function(value) { + var data = [{ scaleid: this.scaleid}]; + this.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; } + if (body.find('[data-field="tool_lp_scale_default_' + value.id + '"]').is(':checked')) { + scaledefault = 1; + } + if (body.find('[data-field="tool_lp_scale_proficient_' + value.id + '"]').is(':checked')) { + proficient = 1; + } if (!scaledefault && !proficient) { return; @@ -136,9 +174,9 @@ define(['jquery', 'core/notification', 'core/templates', 'core/ajax', 'tool_lp/d }); var datastring = JSON.stringify(data); // Send to the hidden field on the form. - $('#tool_lp_scaleconfiguration').val(datastring); + $(this.inputSelector).val(datastring); // Once the configuration has been saved then the original scale ID is set to the current scale ID. - originalscaleid = scaleid; + this.originalscaleid = this.scaleid; }; /** @@ -148,11 +186,11 @@ define(['jquery', 'core/notification', 'core/templates', 'core/ajax', 'tool_lp/d * @param {Number} scaleid The scale ID of the selected scale. * @return {Promise} A deffered object with the scale values. */ - var getScaleValues = function(scaleid) { + ScaleConfig.prototype.getScaleValues = function(scaleid) { return ModScaleValues.get_values(scaleid).then(function(values) { - scalevalues = values; + this.scalevalues = values; return values; - }); + }.bind(this)); }; /** @@ -163,26 +201,28 @@ define(['jquery', 'core/notification', 'core/templates', 'core/ajax', 'tool_lp/d * @return {Void} * @function */ - var scaleChangeHandler = function(e) { + ScaleConfig.prototype.scaleChangeHandler = function(e) { if ($(e.target).val() <= 0) { - $('#id_scaleconfigbutton').prop('disabled', true); + $(this.triggerSelector).prop('disabled', true); } else { - $('#id_scaleconfigbutton').prop('disabled', false); + $(this.triggerSelector).prop('disabled', false); } }; return { + /** * Main initialisation. * + * @param {String} selectSelector The select box selector. + * @param {String} inputSelector The hidden input field selector. + * @param {String} triggerSelector The trigger selector. + * @return {ScaleConfig} A new instance of ScaleConfig. * @method init */ - init: function() { - // Get the current scale ID. - originalscaleid = $("#id_scaleid").val(); - $("#id_scaleid").on('change', scaleChangeHandler).change(); - $('#id_scaleconfigbutton').click(showConfig); + init: function(selectSelector, inputSelector, triggerSelector) { + return new ScaleConfig(selectSelector, inputSelector, triggerSelector); } }; }); diff --git a/admin/tool/lp/classes/form/competency.php b/admin/tool/lp/classes/form/competency.php index a01f57d4b7d..4ce91784001 100644 --- a/admin/tool/lp/classes/form/competency.php +++ b/admin/tool/lp/classes/form/competency.php @@ -93,7 +93,8 @@ class competency extends persistent { $mform->setType('scaleconfiguration', PARAM_RAW); $scaleconfig = $mform->addElement('button', 'scaleconfigbutton', get_string('configurescale', 'tool_lp')); - $PAGE->requires->js_call_amd('tool_lp/scaleconfig', 'init'); + $PAGE->requires->js_call_amd('tool_lp/scaleconfig', 'init', array('#id_scaleid', + '#tool_lp_scaleconfiguration', '#id_scaleconfigbutton')); if ($competency && $competency->has_user_competencies()) { // The scale is used so we "freeze" the element. Though, the javascript code for the scale diff --git a/admin/tool/lp/classes/form/competency_framework.php b/admin/tool/lp/classes/form/competency_framework.php index 5ae3604d6ec..ba59d19bacb 100644 --- a/admin/tool/lp/classes/form/competency_framework.php +++ b/admin/tool/lp/classes/form/competency_framework.php @@ -80,9 +80,10 @@ class competency_framework extends persistent { $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); + $PAGE->requires->js_call_amd('tool_lp/scaleconfig', 'init', array('#id_scaleid', + '#tool_lp_scaleconfiguration', '#id_scaleconfigbutton')); $mform->addElement('selectyesno', 'visible', get_string('visible', 'tool_lp')); diff --git a/admin/tool/lp/templates/scale_configuration_page.mustache b/admin/tool/lp/templates/scale_configuration_page.mustache index f6d074bf989..d1f150296c9 100644 --- a/admin/tool/lp/templates/scale_configuration_page.mustache +++ b/admin/tool/lp/templates/scale_configuration_page.mustache @@ -21,7 +21,7 @@ * none Data attibutes required for JS: - * none + * data-field Context variables required for this template: * scales Array of id / name pairs. @@ -47,8 +47,8 @@ {{#scales}} {{name}} - - + {{/scales}}