From 58f3865fce36572cbedb3ee6d9aacd24ac7efceb Mon Sep 17 00:00:00 2001 From: Frederic Massart Date: Mon, 6 May 2013 14:35:04 +0800 Subject: [PATCH] MDL-39280 form: Multiple select support disabledIf with multiple values --- lib/form/form.js | 51 +++++++++++++++++++++++++++++++++++++++++++++++- lib/formslib.php | 11 ++++++++++- 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/lib/form/form.js b/lib/form/form.js index e9f9490cf34..69d803fb771 100644 --- a/lib/form/form.js +++ b/lib/form/form.js @@ -232,6 +232,7 @@ M.form.initFormDependencies = function(Y, formid, dependencies) { _dependency_eq : function(elements, value) { var lock = false; var hidden_val = false; + var options, v, selected, values; elements.each(function(){ if (this.getAttribute('type').toLowerCase()=='radio' && !Y.Node.getDOMNode(this).checked) { return; @@ -243,14 +244,38 @@ M.form.initFormDependencies = function(Y, formid, dependencies) { lock = lock || hidden_val; return; } - //check for filepicker status if (this.getAttribute('class').toLowerCase() == 'filepickerhidden') { + // Check for filepicker status. var elementname = this.getAttribute('name'); if (elementname && M.form_filepicker.instances[elementname].fileadded) { lock = false; } else { lock = true; } + } else if (this.get('nodeName').toUpperCase() === 'SELECT' && this.get('multiple') === true) { + // Multiple selects can have one or more value assigned. A pipe (|) is used as a value separator + // when multiple values have to be selected at the same time. + values = value.split('|'); + selected = []; + options = this.get('options'); + options.each(function() { + if (this.get('selected')) { + selected[selected.length] = this.get('value'); + } + }); + if (selected.length > 0 && selected.length === values.length) { + for (var i in selected) { + v = selected[i]; + if (values.indexOf(v) > -1) { + lock = true; + } else { + lock = false; + return; + } + } + } else { + lock = false; + } } else { lock = lock || this.get('value') == value; } @@ -288,6 +313,30 @@ M.form.initFormDependencies = function(Y, formid, dependencies) { } else { lock = false; } + } else if (this.get('nodeName').toUpperCase() === 'SELECT' && this.get('multiple') === true) { + // Multiple selects can have one or more value assigned. A pipe (|) is used as a value separator + // when multiple values have to be selected at the same time. + values = value.split('|'); + selected = []; + options = this.get('options'); + options.each(function() { + if (this.get('selected')) { + selected[selected.length] = this.get('value'); + } + }); + if (selected.length > 0 && selected.length === values.length) { + for (var i in selected) { + v = selected[i]; + if (values.indexOf(v) > -1) { + lock = false; + } else { + lock = true; + return; + } + } + } else { + lock = true; + } } else { lock = lock || this.get('value') != value; } diff --git a/lib/formslib.php b/lib/formslib.php index 201da0c097c..9499b5c7461 100644 --- a/lib/formslib.php +++ b/lib/formslib.php @@ -2233,12 +2233,21 @@ function validate_' . $this->_formName . '(frm) { * is checked. If $condition is something else (like "eq" for equals) then it is checked to see if the value * of the $dependentOn element is $condition (such as equal) to $value. * + * When working with multiple selects, the dependentOn has to be the real name of the select, meaning that + * it will most likely end up with '[]'. Also, the value should be an array of required values, or a string + * containing the values separated by pipes: array('red', 'blue') or 'red|blue'. + * * @param string $elementName the name of the element which will be disabled * @param string $dependentOn the name of the element whose state will be checked for condition * @param string $condition the condition to check * @param mixed $value used in conjunction with condition. */ - function disabledIf($elementName, $dependentOn, $condition = 'notchecked', $value='1'){ + function disabledIf($elementName, $dependentOn, $condition = 'notchecked', $value='1') { + // Multiple selects allow for a multiple selection, we transform the array to string here as + // an array cannot be used as a key in an associative array. + if (is_array($value)) { + $value = implode('|', $value); + } if (!array_key_exists($dependentOn, $this->_dependencies)) { $this->_dependencies[$dependentOn] = array(); }