Fix issues with field dependencies
authorMatthias Schmidt <gravatronics@live.com>
Sun, 6 May 2018 10:59:07 +0000 (12:59 +0200)
committerMatthias Schmidt <gravatronics@live.com>
Sun, 6 May 2018 10:59:07 +0000 (12:59 +0200)
See #2509

wcfsetup/install/files/js/WoltLabSuite/Core/Form/Builder/Field/Dependency/Abstract.js
wcfsetup/install/files/js/WoltLabSuite/Core/Form/Builder/Field/Dependency/Manager.js
wcfsetup/install/files/js/WoltLabSuite/Core/Form/Builder/Field/Dependency/Value.js

index aa45a37092bc0925139b59bb4a34bf90120f0d4a..09371f531118cd00a45c3d865e33381ed0075091 100644 (file)
@@ -70,19 +70,27 @@ define(['./Manager'], function(DependencyManager) {
                        
                        this._field = elById(fieldId);
                        if (this._field === null) {
-                               throw new Error("Unknown field with id '" + fieldId + "'.");
-                       }
-                       
-                       this._fields = [this._field];
-                       
-                       // handle special case of boolean form fields that have to form fields
-                       if (this._field.tagName === 'INPUT' && this._field.type === 'radio' && elData(this._field, 'no-input-id') !== '') {
-                               this._noField = elById(elData(this._field, 'no-input-id'));
-                               if (this._noField === null) {
-                                       throw new Error("Cannot find 'no' input field for input field '" + fieldId + "'");
+                               this._fields = [];
+                               elBySelAll('input[type=radio][name=' + fieldId + ']', undefined, function(field) {
+                                       this._fields.push(field);
+                               }.bind(this));
+                               
+                               if (!this._fields.length) {
+                                       throw new Error("Unknown field with id '" + fieldId + "'.");
                                }
+                       }
+                       else {
+                               this._fields = [this._field];
                                
-                               this._fields.push(this._noField);
+                               // handle special case of boolean form fields that have to form fields
+                               if (this._field.tagName === 'INPUT' && this._field.type === 'radio' && elData(this._field, 'no-input-id') !== '') {
+                                       this._noField = elById(elData(this._field, 'no-input-id'));
+                                       if (this._noField === null) {
+                                               throw new Error("Cannot find 'no' input field for input field '" + fieldId + "'");
+                                       }
+                                       
+                                       this._fields.push(this._noField);
+                               }
                        }
                        
                        DependencyManager.addDependency(this);
index b7b846e043e90a279f2d222e69c17eea251239d4..4b92442c7840c51bf8675c1856c7043d5f7cc4ed 100644 (file)
@@ -150,8 +150,10 @@ define(['Dictionary', 'Dom/ChangeListener', 'EventHandler', 'List', 'Dom/Util',
                        var fields = dependency.getFields();
                        for (var i = 0, length = fields.length; i < length; i++) {
                                var field = fields[i];
-                               if (!_fields.has(field.id)) {
-                                       _fields.set(field.id, field);
+                               var id = DomUtil.identify(field);
+                               
+                               if (!_fields.has(id)) {
+                                       _fields.set(id, field);
                                        
                                        if (field.tagName === 'INPUT' && (field.type === 'checkbox' || field.type === 'radio')) {
                                                field.addEventListener('change', this.checkDependencies.bind(this));
@@ -186,7 +188,7 @@ define(['Dictionary', 'Dom/ChangeListener', 'EventHandler', 'List', 'Dom/Util',
                                        }
                                }
                                
-                               // no node dependencies is met
+                               // no node dependency is met
                                this._hide(dependentNode);
                        }.bind(this));
                        
@@ -247,7 +249,18 @@ define(['Dictionary', 'Dom/ChangeListener', 'EventHandler', 'List', 'Dom/Util',
                 * @return      {boolean}
                 */
                isHiddenByDependencies: function(node) {
-                       return _dependencyHiddenNodes.has(node);
+                       if (_dependencyHiddenNodes.has(node)) {
+                               return true;
+                       }
+                       
+                       var returnValue = false;
+                       _dependencyHiddenNodes.forEach(function(hiddenNode) {
+                               if (DomUtil.contains(hiddenNode, node)) {
+                                       returnValue = true;
+                               }
+                       });
+                       
+                       return returnValue;
                },
                
                /**
index d0b157325d3b172d1bd8d90592f62e7f8b59f63e..758b69047b89fd83c88eec75938afb1527046b1f 100644 (file)
@@ -8,7 +8,7 @@
  * @see        module:WoltLabSuite/Core/Form/Builder/Field/Dependency/Abstract
  * @since      3.2
  */
-define(['./Abstract', 'Core'], function(Abstract, Core) {
+define(['./Abstract', 'Core', './Manager'], function(Abstract, Core, Manager) {
        "use strict";
        
        /**
@@ -26,9 +26,33 @@ define(['./Abstract', 'Core'], function(Abstract, Core) {
                                throw new Error("Values have not been set.");
                        }
                        
+                       var value;
+                       if (this._field) {
+                               if (Manager.isHiddenByDependencies(this._field)) {
+                                       return false;
+                               }
+                               
+                               value = this._field.value;
+                       }
+                       else {
+                               for (var i = 0, length = this._fields.length, field; i < length; i++) {
+                                       field = this._fields[i];
+                                       
+                                       if (field.checked) {
+                                               if (Manager.isHiddenByDependencies(field)) {
+                                                       return false;
+                                               }
+                                               
+                                               value = field.value;
+                                               
+                                               break;
+                                       }
+                               }
+                       }
+                       
                        // do not use `Array.prototype.indexOf()` as we use a weak comparision
                        for (var i = 0, length = this._values.length; i < length; i++) {
-                               if (this._values[i] == this._field.value) {
+                               if (this._values[i] == value) {
                                        return true;
                                }
                        }