Fix form field dependency-related issues
authorMatthias Schmidt <gravatronics@live.com>
Sat, 13 Jan 2018 16:58:46 +0000 (17:58 +0100)
committerMatthias Schmidt <gravatronics@live.com>
Sat, 13 Jan 2018 16:58:46 +0000 (17:58 +0100)
See #2509

wcfsetup/install/files/acp/templates/__formContainerDependencies.tpl
wcfsetup/install/files/js/WoltLabSuite/Core/Form/Builder/Field/Dependency/Container/Default.js
wcfsetup/install/files/js/WoltLabSuite/Core/Form/Builder/Field/Dependency/Container/Tab.js
wcfsetup/install/files/js/WoltLabSuite/Core/Form/Builder/Field/Dependency/Container/TabMenu.js
wcfsetup/install/files/js/WoltLabSuite/Core/Form/Builder/Field/Dependency/Manager.js
wcfsetup/install/files/lib/system/form/builder/TFormNode.class.php
wcfsetup/install/files/lib/system/form/builder/field/dependency/ValueFormFieldDependency.class.php

index e9daa97fdebf754034df7a253907763ce76f192f..20b7a7477ef044f180a076cd4f2e8e44c4cd3dc7 100644 (file)
@@ -1,6 +1,6 @@
 {if !$container->getDependencies()|empty}
        <script data-relocate="true">
-               {foreach from=$field->getDependencies() item=dependency}
+               {foreach from=$container->getDependencies() item=dependency}
                        {@$dependency->getHtml()}
                {/foreach}
        </script>
index 6432c3de5321ea15287eb3d0b1c1188de0fda664..67b4129db684744e37e0ab73f700ccb24d6f37ba 100644 (file)
@@ -23,6 +23,11 @@ define(['./Abstract', 'Core', '../Manager'], function(Abstract, Core, Dependency
                 * @see WoltLabSuite/Core/Form/Builder/Field/Dependency/Container/Default#checkContainer
                 */
                checkContainer: function() {
+                       // only consider containers that have not been hidden by their own dependencies
+                       if (DependencyManager.isHiddenByDependencies(this._container)) {
+                               return;
+                       }
+                       
                        var containerIsVisible = !elIsHidden(this._container);
                        var containerShouldBeVisible = false;
                        
index a561b89697f5ffc6d5b28cd135fc775e025aea28..0a8c38b0b4102fb6ed65c316f9266d24daba76e2 100644 (file)
@@ -23,6 +23,11 @@ define(['./Abstract', 'Core', 'Dom/Util', '../Manager'], function(Abstract, Core
                 * @see WoltLabSuite/Core/Form/Builder/Field/Dependency/Container/Default#checkContainer
                 */
                checkContainer: function() {
+                       // only consider containers that have not been hidden by their own dependencies
+                       if (DependencyManager.isHiddenByDependencies(this._container)) {
+                               return;
+                       }
+                       
                        var containerIsVisible = !elIsHidden(this._container);
                        var containerShouldBeVisible = false;
                        
index e957a4275c721cca700b2d7b6efa5689a81a6500..8f9b039d0a72578c6be4ae572b1a3fca72315f33 100644 (file)
@@ -23,6 +23,11 @@ define(['./Abstract', 'Core', 'Dom/Util', '../Manager'], function(Abstract, Core
                 * @see WoltLabSuite/Core/Form/Builder/Field/Dependency/Container/Default#checkContainer
                 */
                checkContainer: function() {
+                       // only consider containers that have not been hidden by their own dependencies
+                       if (DependencyManager.isHiddenByDependencies(this._container)) {
+                               return;
+                       }
+                       
                        var containerIsVisible = !elIsHidden(this._container);
                        var containerShouldBeVisible = false;
                        
index 70e656a48c62c4b203c725934283327f4f8ffaef..fe8807ebe6fccc9bf1514f636274131ece2fa234 100644 (file)
@@ -7,7 +7,7 @@
  * @module     WoltLabSuite/Core/Form/Builder/Field/Dependency/Manager
  * @since      3.2
  */
-define(['Dictionary', 'EventHandler'], function(Dictionary, EventHandler) {
+define(['Dictionary', 'EventHandler', 'List'], function(Dictionary, EventHandler, List) {
        "use strict";
        
        /**
@@ -25,6 +25,13 @@ define(['Dictionary', 'EventHandler'], function(Dictionary, EventHandler) {
         */
        var _checkContainersAgain = true;
        
+       /**
+        * list of containers hidden due to their own dependencies
+        * @type        {List}
+        * @private
+        */
+       var _dependencyHiddenNodes = new List();
+       
        /**
         * list if fields for which event listeners have been registered
         * @type        {Dictionary}
@@ -40,6 +47,28 @@ define(['Dictionary', 'EventHandler'], function(Dictionary, EventHandler) {
        var _nodeDependencies = new Dictionary();
        
        return {
+               /**
+                * Hides the given node because of its own dependencies.
+                * 
+                * @param       {HTMLElement}   node    hidden node
+                * @protected
+                */
+               _hide: function(node) {
+                       elHide(node);
+                       _dependencyHiddenNodes.add(node.id);
+               },
+               
+               /**
+                * Shows the given node because of its own dependencies.
+                *
+                * @param       {HTMLElement}   node    shown node
+                * @protected
+                */
+               _show: function(node) {
+                       elShow(node);
+                       _dependencyHiddenNodes.delete(node.id);
+               },
+               
                /**
                 * Registers a new form field dependency.
                 * 
@@ -88,14 +117,14 @@ define(['Dictionary', 'EventHandler'], function(Dictionary, EventHandler) {
                                for (var i = 0, length = nodeDependencies.length; i < length; i++) {
                                        // if any dependency is met, the element is visible
                                        if (nodeDependencies[i].checkDependency()) {
-                                               elShow(dependentNode);
+                                               this._show(dependentNode);
                                                return;
                                        }
                                }
                                
                                // no node dependencies is met
-                               elHide(dependentNode);
-                       });
+                               this._hide(dependentNode);
+                       }.bind(this));
                        
                        // delete dependencies for removed elements
                        for (var i = 0, length = obsoleteNodes.length; i < length; i++) {
@@ -146,5 +175,15 @@ define(['Dictionary', 'EventHandler'], function(Dictionary, EventHandler) {
                                this.checkContainers();
                        }
                },
+               
+               /**
+                * Returns `true` if the given node has been hidden because of its own dependencies.
+                * 
+                * @param       {HTMLElement}   node    checked node
+                * @return      {boolean}
+                */
+               isHiddenByDependencies: function(node) {
+                       return _dependencyHiddenNodes.has(container.id);
+               }
        };
 });
index 26310dd5a321871a4f41dea4c935e21dc387ac35..2b92600a02e0d0d32894eb8bef72bb30f6265a44 100644 (file)
@@ -114,6 +114,19 @@ trait TFormNode {
         * @return      bool
         */
        public function checkDependencies() {
+               if (!empty($this->dependencies)) {
+                       $hasMetDependency = false;
+                       foreach ($this->dependencies as $dependency) {
+                               if ($dependency->checkDependency()) {
+                                       $hasMetDependency = true;
+                               }
+                       }
+                       
+                       if (!$hasMetDependency) {
+                               return false;
+                       }
+               }
+               
                if ($this instanceof IFormParentNode) {
                        if (count($this) > 0) {
                                /** @var IFormChildNode $child */
@@ -130,16 +143,6 @@ trait TFormNode {
                        return false;
                }
                
-               if (!empty($this->dependencies)) {
-                       foreach ($this->dependencies as $dependency) {
-                               if ($dependency->checkDependency()) {
-                                       return true;
-                               }
-                       }
-                       
-                       return false;
-               }
-               
                return true;
        }
        
index 0b06f0ea68e8978432fc288331c719867b53dfef..6340a9f158716e884521d610074b6f81f1575868 100644 (file)
@@ -26,7 +26,7 @@ class ValueFormFieldDependency extends AbstractFormFieldDependency {
         * @inheritDoc
         */
        public function checkDependency() {
-               return !empty($this->getField()->getValue());
+               return in_array($this->getField()->getValue(), $this->getValues());
        }
        
        /**