В AngularJS проверки группа проверки окно


у меня есть список флажков, из которых хотя бы один является обязательным. Я пытался добиться этого с помощью проверки 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>

вот код в plunker:http://plnkr.co/edit/Bz9yhSoPYUNzFDpfASwt?p=preview Кто-нибудь делал это на AngularJS? Делая флажки обязательными, заставляет меня выбирать все значения флажков. Эта проблема также не задокументирована в документации AngularJS.

4   51  

4 ответа:

если вы хотите, чтобы хотя бы один элемент в группе был выбран, можно определить dynamic требуются С ng-требуется.

для гендерных переключателей это было бы легко:

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

Checkbox group тоже было бы легко, если бы вы использовали массив для хранения выбранных фруктов (просто проверьте длину массива), но с объектом необходимо проверить, установлено ли какое-либо из значений 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)"
>

обновление:

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

также имейте в виду, что он будет возвращать false, если значение равно 0.

спасибо Klaster_1 за принятый ответ. Я построил на этом с помощью ng-change на входах флажка установить локальную переменную области видимости, которая будет использоваться как ng-required выражение. Это предотвращает запуск someSelected() на каждый переварит.

вот plunkr, демонстрирующий этот: http://embed.plnkr.co/ScqA4aqno5XFSp9n3q6d/

вот 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();
  });

хорошо, может быть, очень поздно на вечеринку, но если у вас есть массив объектов, на которые вы смотрите, решение просто проверить длину массива выбранных объектов работало для меня.
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

$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];
        }
    }
}

Я понимаю, что происходит в этом решении, что вы проверяете все параметры галочку, чтобы знать, кто нажал. Но из того, что я знаю, это, безусловно, самое простое решение(понять и реализовать), и оно работает как очарование, если вы знаете, что ваши возможности будут ограничены. Для более оптимизированное решение. Проверьте ответы выше.

мы можем достигнуть вашего требования без проходить весь экземпляр флажков. Вот пример кода

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

здесь я обертываю функцию 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>