使复选框不需要启用按钮(如果隐藏)

Make checkboxes not required to enable button if hidden

本文关键字:如果 隐藏 按钮 复选框 不需要 启用      更新时间:2023-09-26

我在一个页面上有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>

allCheckBoxesReChecked函数为:

$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语句更容易/更干净,代码更少?谢谢

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

<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 check是一个!migrationState…),你可以有完整的对象需求,而不是简单的字符串,其变量可以用作选择正确测试的标志,例如

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

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

将复选框放入表单并使用ng必需属性,然后仅在表单有效时启用按钮:

    <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="..."

您可以在其他地方执行复选框的显示逻辑,这样您就可以执行以下操作:

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显示中使用这些范围变量。然后你可以这样做:

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