【问题标题】:Make checkboxes not required to enable button if hidden如果隐藏,使复选框不需要启用按钮
【发布时间】:2014-10-03 07:17:17
【问题描述】:

我在一个页面上有 4 个复选框和一个在选中复选框之前未启用的按钮。当某些复选框被隐藏时,我遇到了问题。当它们被隐藏时,我无法检查它们,然后该按钮将永远不会启用,因为所有框都未选中。我想要做的是使复选框不需要启用按钮,如果它们被隐藏。我在脑海中描绘它的方式将是一长串 if/else 语句,而且会很丑陋和复杂。我知道必须有一个更简单的解决方案,我似乎无法理解它会是什么。我将提供复选框和按钮的代码,然后描述我认为可行的方法,以便您了解为什么我认为可能有更简单的方法。此外,我们在这个网络应用程序中使用了 Angular。不确定这是否会对解决方案产生影响,但我想我会提到它。

复选框的代码是:

<div>
    <input type="checkbox" id="bes-confirmation" ng-model="checkboxes.besConfirmation" ng-show="migrationState.migrationData.usersWithBESEnabled.length > 0" />
    <label for="bes-confirmation" ng-show="migrationState.migrationData.usersWithBESEnabled.length > 0" >I understand -- BES</label>
    <br />
    <input type="checkbox" id="public-folder-confirmation" ng-model="checkboxes.publicFolderConfirmation" ng-show="migrationState.migrationData.publicFoldersEnabled"/>
    <label for="public-folder-confirmation" ng-show="migrationState.migrationData.publicFoldersEnabled" >I understand -- PF</label>
    <br />
    <input type="checkbox" id="adr-confirmation" ng-model="checkboxes.adrConfirmation" ng-show="!migrationState.migrationData.adrRecordIsCorrect" />
    <label for="adr-confirmation" ng-show="!migrationState.migrationData.adrRecordIsCorrect" >I understand -- ADR</label>
    <br />
    <input type="checkbox" id="sdr-confirmation" ng-model="checkboxes.sdrConfirmation" ng-show="migrationState.migrationData.splitDomainRoutingEnabled"/>
    <label for="sdr-confirmation" ng-show="migrationState.migrationData.splitDomainRoutingEnabled">I understand -- SDR</label>
</div>

按钮是:

<button type="button" 
            ng-click="scheduleMigration()"
            ng-disabled="!allCheckboxesAreChecked()">               
            Schedule Migration!
</button>

allCheckBoxesAreChecked 函数是:

$scope.allCheckboxesAreChecked = function() {
    return $scope.checkboxes.besConfirmation && $scope.checkboxes.adrConfirmation && $scope.checkboxes.sdrConfirmation && $scope.checkboxes.publicFolderConfirmation;
}

我想我可以有一系列类似的 if/else 语句(为简单起见,我将用伪代码编写)

if !publicFoldersEnabled
  return besConfirmation && sdrConfirmation && adrConfirmation
else if !splitDomainRoutingEnabled
  return sdrConfirmation && adrConfirmation && publicFolderConfirmation

等等……

我可以继续使用所有可能的可见和隐藏复选框组合,但我觉得必须有更好的方法来做到这一点。关于如何比一系列 if/else 语句更容易/更清洁并且代码更少的任何想法?谢谢!

【问题讨论】:

    标签: javascript html angularjs checkbox


    【解决方案1】:

    最简单的方法是规范所有复选框的行为。使所有复选框看起来像:

    <input type="checkbox" ng-model="checkboxes.someUniqueName" ng-show=migrationState.migrationData.someUniqueName"/>
    

    然后您可以在某个数组中引用您希望监控的所有复选框:

    var requirements = ['someUniqueName1', 'someUniqueName2', ... ];
    

    最后,只需重写你的验证函数来循环它:

    $scope.validateCheckboxes = function() {
        var okay = true ;
        angular.forEach(requirements, function(req, index) {
            okay = okay && ($scope.checkboxes[req] || !$scope.migrationState.migrationData[req]);
        return okay;
    };
    

    如果您真的希望保留复选框特定的行为(例如 ng-show 检查为 !migrationState... 的一个复选框),您可以拥有完整的对象而不是简单的字符串,其变量可以是用作选择正确测试的标志,例如

    var requirements = [{'name':'someUniqueName1', 'reverse':false, 'checkLength':true}, ...]   
    

    这种设置具有易于扩展的额外优势:如果您添加了另一个复选框,只需向您的需求数组添加一个字符串即可。

    【讨论】:

    • 谢谢!我认为这会奏效。感谢您的帮助。
    【解决方案2】:

    将您的复选框放在表单中并使用 ng-required 属性,然后仅当表单有效时才启用按钮:

        <form name="form" ng-submit="scheduleMigration()">
          <div ng-show="migrationState.migrationData.usersWithBESEnabled.length &gt; 0">
            <input type="checkbox" id="bes-confirmation" ng-model="checkboxes.besConfirmation" ng-required="migrationState.migrationData.usersWithBESEnabled.length &gt; 0" />
            <label for="bes-confirmation">I understand -- BES</label>
          </div> 
          ...
          <!-- other checkboxes -->
          ...
          <button type="submit" ng-disabled="!form.$valid">Schedule Migration!</button>
        </form>
    

    如果你使用ng-if 而不是ng-show,你可以让它更短——在这种情况下,元素根本不在DOM 树中,所以你可以只用required 替换ng-required="..."

    【讨论】:

    • 感谢您的建议!我可以看到这是如何工作的。不过还是会选择 Sycomor 的解决方案。
    【解决方案3】:

    您可以在其他地方执行复选框的显示逻辑,以便您拥有,也许是这样的:

    scope.visibleCheckboxes.besConfirmation = migrationState.migrationData.usersWithBESEnabled.length > 0
    scope.visibleCheckboxes.publicFolderConfirmation = migrationState.migrationData.publicFoldersEnabled
    scope.visibleCheckboxes.adrConfirmation = !migrationState.migrationData.adrRecordIsCorrect
    scope.visibleCheckboxes.sdrConfirmation = migrationState.migrationData.splitDomainRoutingEnabled
    

    然后在您的 ng-show 中使用这些范围变量。然后你可以这样做:

    function allCheckboxesAreChecked() {
        var vC = scope.visibleCheckboxes
        for ( checkbox in vC ) {
            if ( vC.hasOwnProperty(checkbox) && vc[checkbox] && !scope.checkboxes[checkbox] ) {
                return false;
            }
        }
        return true;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-13
      • 2011-02-01
      • 2016-04-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多