jQuery AngularJS 组复选框验证

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19632933/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 00:20:16  来源:igfitidea点击:

AngularJS group check box validation

javascriptjqueryangularjs

提问by Pradeep Jaiswar

I have a list of check boxes, of which at least one is compulsory. I have tried to achieve this via AngularJS validation, but had a hard time. Below is my code:

我有一个复选框列表,其中至少有一个是强制性的。我试图通过 AngularJS 验证来实现这一点,但很难。下面是我的代码:

// Code goes here for js 

var app = angular.module('App', []);

function Ctrl($scope) {
  $scope.formData = {};
  $scope.formData.selectedGender = '';
  $scope.gender = [{
    'name': 'Male',
    'id': 1
  }, {
    'name': 'Female',
    'id': 2
  }];
  $scope.formData.selectedFruits = {};
  $scope.fruits = [{
    'name': 'Apple',
    'id': 1
  }, {
    'name': 'Orange',
    'id': 2
  }, {
    'name': 'Banana',
    'id': 3
  }, {
    'name': 'Mango',
    'id': 4
  }, ];
  $scope.submitForm = function() {

  }
}
// Code goes here for html
<!doctype html>
<html ng-app="App">

<head>
  <!-- css file -->
  <!--App file -->
  <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.js"></script>
  <!-- External file -->
</head>

<body>
  <div ng-controller="Ctrl">
    <form class="Scroller-Container">
      <div ng-app>

        <form class="Scroller-Container" ng-submit="submit()" ng-controller="Ctrl">
          <div>
            What would you like?
            <div ng-repeat="(key, val) in fruits">
              <input type="checkbox" ng-model="formData.selectedFruits[val.id]" name="group[]" id="group[{{val.id}}]" required />{{val.name}}
            </div>
            <br />
            <div ng-repeat="(key, val) in gender">
              <input type="radio" ng-model="$parent.formData.selectedGender" name="formData.selectedGender" id="{{val.id}}" value="{{val.id}}" required />{{val.name}}
            </div>
            <br />
          </div>
          <pre>{{formData.selectedFruits}}</pre>
          <input type="submit" id="submit" value="Submit" />
        </form>
      </div>
      <br>
    </form>
  </div>
</body>

</html>

Here is the code in plunker: http://plnkr.co/edit/Bz9yhSoPYUNzFDpfASwt?p=previewHas anyone done this on AngularJS? Making the checkboxes required, forces me to select all the checkbox values. This problem is also not documented in the AngularJS documentation.

这是 plunker 中的代码:http://plnkr.co/edit/Bz9yhSoPYUNzFDpfASwt?p=preview有没有人在 AngularJS 上做过这个?使复选框成为必需,迫使我选择所有复选框值。这个问题也没有记录在 AngularJS 文档中。

回答by Klaster_1

If you want to require at least one item in group being selected, it's possible to define dynamic requiredattribute with ng-required.

如果您想要求选择组中的至少一项,则可以使用ng-required定义动态required属性。

For gender radio buttons this would be easy:

对于性别单选按钮,这很容易:

<input
    type="radio"
    ng-model="formData.selectedGender"
    value="{{val.id}}"
    ng-required="!formData.selectedGender"
>

Checkbox group would be easy too, if you used array to store selected fruits (just check array length), but with object it's necessary to check if any of values are set to true with filter or function in controller:

复选框组也很容易,如果您使用数组来存储选定的水果(只需检查数组长度),但是对于对象,有必要检查是否有任何值通过控制器中的过滤器或函数设置为 true:

$scope.someSelected = function (object) {
  return Object.keys(object).some(function (key) {
    return object[key];
  });
}
<input
    type="checkbox"
    value="{{val.id}}"
    ng-model="formData.selectedFruits[val.id]"
    ng-required="!someSelected(formData.selectedFruits)"
>

Update:

更新:

const someSelected = (object = {}) => Object.keys(object).some(key => object[key])

Also keep in mind that it will return false if value is 0.

还要记住,如果值为 0,它将返回 false。

回答by Saras Arya

Okay maybe very late to the party but if you have an array of objects which you are looking at, the solution of just checking the length of array of selected objects worked for me.
HTML

好吧,聚会可能很晚了,但是如果您正在查看一组对象,那么仅检查所选对象数组长度的解决方案对我有用。
HTML

<div ng-repeat="vehicle in vehicles">
    <input type="checkbox" name="car" ng-model="car.ids[vehicle._id]" ng-required=" car.objects.length <= 0"> {{vehicle.model}} {{vehicle.brand}} <b>{{vehicle.geofenceName}}</b>
</div>

JS

JS

$scope.vehicles = [{},{}] // Your array of objects;
$scope.car = {
    ids: {},
    objects: []
};

$scope.$watch(function() {
    return $scope.car.ids;
}, function(value) {
    $scope.car.objects = [];
    angular.forEach($scope.car.ids, function(value, key) {
        value && $scope.car.objects.push(getCategoryById(key));
    });
}, true);

function getCategoryById(id) {
    for (var i = 0; i < $scope.vehicles.length; i++) {
        if ($scope.vehicles[i]._id == id) {
            return $scope.vehicles[i];
        }
    }
}

I understand what is happening in this solution that you are checking all the checkbox options to know which one is clicked. But from what I know this is by far the easiest solution(to understand and implement) and it works like a charm if you know that your options will be limited. For a more time optimized solution. Check the answers above.

我了解此解决方案中发生的情况,您正在检查所有复选框选项以了解单击了哪个选项。但据我所知,这是迄今为止最简单的解决方案(理解和实施),如果您知道您的选择将受到限制,它就像一个魅力。获得更多时间优化的解决方案。检查上面的答案。

回答by Tom Spencer

Thanks to Klaster_1 for the accepted answer. I've built on this by using ng-changeon the checkbox inputs to set a local scope variable, which would be used as the ng-requiredexpression. This prevents the running of someSelected()on every digest.

感谢 Klaster_1 接受的答案。我已经通过ng-change在复选框输入上使用来设置本地范围变量来构建此变量,该变量将用作ng-required表达式。这可以防止someSelected()在每个摘要上运行。

Here is a plunkr demonstrating this: http://embed.plnkr.co/ScqA4aqno5XFSp9n3q6d/

这是一个 plunkr 演示:http://embed.plnkr.co/ScqA4aqno5XFSp9n3q6d/

Here is the HTML and JS for posterity.

这是供后代使用的 HTML 和 JS。

<!DOCTYPE html>
<html ng-app="App">

<head>
  <meta charset="utf-8" />
  <script data-require="[email protected]" data-semver="1.4.9" src="https://code.angularjs.org/1.4.9/angular.js"></script>
  <script src="script.js"></script>
</head>

<body>
  <div ng-controller="AppCtrl">
    <form class="Scroller-Container" name="multipleCheckbox" novalidate="">
      <h3>What would you like?</h3>
      <div ng-repeat="fruit in fruits">
        <input type="checkbox" ng-model="formData.selectedFruits[fruit.name]" ng-change="checkboxChanged()" ng-required="!someSelected" /> {{fruit.name}}
      </div>
      <p style="color: red;" ng-show="multipleCheckbox.$error.required">You must choose one fruit</p>
    </form>
    <pre>Fruits model:
{{formData.selectedFruits | json}}</pre>
  </div>
</body>

</html>
angular
  .module('App', [])
  .controller('AppCtrl', function($scope) {

    var selectedFruits = {
      Mango: true
    };

    var calculateSomeSelected = function() {
      $scope.someSelected = Object.keys(selectedFruits).some(function(key) {
        return selectedFruits[key];
      });
    };

    $scope.formData = {
      selectedFruits: selectedFruits
    };

    $scope.fruits = [{
      'name': 'Apple'
    }, {
      'name': 'Orange'
    }, {
      'name': 'Banana'
    }, {
      'name': 'Mango'
    }];

    $scope.checkboxChanged = calculateSomeSelected;

    calculateSomeSelected();
  });

回答by Vivek Kumar

We can achieve your requirement without traversing all check-boxes instance. Here is the sample code

我们可以在不遍历所有复选框实例的情况下实现您的要求。这是示例代码

<script>
angular.module('atLeastOneExample', [])
.controller('ExampleController', ['$scope', function($scope) {
  $scope.e = function(s){
    eval(s);
  };
}]);
</script>

Here i am wrapping javascript eval function in "e" function to access it.

在这里,我将 javascript eval 函数包装在“e”函数中以访问它。

<form name="myForm" ng-controller="ExampleController" ng-init="c=0">
  <label>
      Value1: <input type="checkbox" ng-model="checkboxModel.value[0]" ng-change="e('($scope.checkboxModel.value[0])?$scope.c++:$scope.c--')"/>
  </label><br/>
  <label>
      Value2: <input type="checkbox" ng-model="checkboxModel.value[1]" ng-change="e('($scope.checkboxModel.value[1])?$scope.c++:$scope.c--')"/>
  </label><br/>
  value = {{checkboxModel.value}}<br/>
  isAtLeastOneChecked = {{c>0}}
</form>