admin管理员组

文章数量:1178528

I am trying to force a single-selection on checkboxes, similar to a html "select"

I have a html simple table:

<tr ng-repeat="subscription in entities">
    <td>
        <input type="checkbox" ng-checked="isChecked(subscription)" ng-click="toggleSelection(subscription)"/>
    </td>
</tr> 

Then I have some simple controller functions for those directives above:

$scope.isChecked = function(entity) {
    return $scope.checkedEntity === entity;
};

$scope.toggleSelection = function(entity) {
    entity.checked = !entity.checked;
    if (entity.checked) {
        $scope.checkedEntity = entity;
    } else {
        $scope.checkedEntity = null;
    }
};

Unfortunately it doesn't work, and I think I just discovered why.... the ng-click has 0 priority, vs 100 for ng-checked.

Is there an elegant solution for this problem?

I am trying to force a single-selection on checkboxes, similar to a html "select"

I have a html simple table:

<tr ng-repeat="subscription in entities">
    <td>
        <input type="checkbox" ng-checked="isChecked(subscription)" ng-click="toggleSelection(subscription)"/>
    </td>
</tr> 

Then I have some simple controller functions for those directives above:

$scope.isChecked = function(entity) {
    return $scope.checkedEntity === entity;
};

$scope.toggleSelection = function(entity) {
    entity.checked = !entity.checked;
    if (entity.checked) {
        $scope.checkedEntity = entity;
    } else {
        $scope.checkedEntity = null;
    }
};

Unfortunately it doesn't work, and I think I just discovered why.... the ng-click has 0 priority, vs 100 for ng-checked.

Is there an elegant solution for this problem?

Share Improve this question edited Apr 24, 2014 at 21:47 Jon Harding 4,94614 gold badges53 silver badges98 bronze badges asked Apr 24, 2014 at 21:22 BrianBrian 3381 gold badge3 silver badges14 bronze badges 3
  • can you share your $scope objects – Jon Harding Commented Apr 24, 2014 at 21:42
  • I'm sorry I don't get what you mean? – Brian Commented Apr 24, 2014 at 21:57
  • why not just use type="radio"? – Norbert Norbertson Commented Jul 17, 2018 at 13:24
Add a comment  | 

4 Answers 4

Reset to default 25

Bind ng-model to subscription.checked, and have ng-click uncheck all subscriptions except the one clicked. Since these are checkboxes, the one clicked will toggle itself.

<tr ng-repeat="subscription in entities">
  <td>
    <input ng-model="subscription.checked" ng-click="updateSelection($index, entities)" type="checkbox" />
  </td>
</tr>

You can use a plain for loop, but angular's forEach allows us to alias each item as subscription and improve readability:

$scope.updateSelection = function(position, entities) {
  angular.forEach(entities, function(subscription, index) {
    if (position != index) 
      subscription.checked = false;
  });
}

Here is a working demo: http://plnkr.co/edit/XD7r6PoTWpI4cBjdIZtv?p=preview

<!DOCTYPE html>
<html>

<head>
  <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
  <script>
    angular.module('app', []).controller('appc', ['$scope',
      function($scope) {
        $scope.selected = 'other';
      }
    ]);
  </script>
</head>

<body ng-app="app" ng-controller="appc">
  <label>SELECTED: {{selected}}</label>
  <div>
    <input type="checkbox" ng-checked="selected=='male'" ng-true-value="'male'" ng-model="selected">Male
    <br>
    <input type="checkbox" ng-checked="selected=='female'" ng-true-value="'female'" ng-model="selected">Female
    <br>
    <input type="checkbox" ng-checked="selected=='other'" ng-true-value="'other'" ng-model="selected">Other
  </div>



</body>

</html>

I have used the below code to achieve the similar functionality. Trick is to use ng-click which can yield this pretty nicely. checkbox-1 & checkbox-2 are boolean in nature.

<form>
    <input type="checkbox" ng-click="checkbox-2 = false" ng-model="checkbox-1" >
    <input type="checkbox" ng-click="checkbox-1 = false" ng-model="checkbox-2" >
</form>

Off the top of my head, I'd suggest one of three options for you.

  1. Write a directive that will set up the checkboxes for you and manage the state within them. This isn't ideal, because you're turning a rule about your model (only one subscription should be checked) into DOM manipulation problem.
  2. Structure your model such that only one subscription is ever marked active. This is tricky, because modifying the model on a change will kick off another digest cycle, not what you want.
  3. Use radio buttons instead of checkboxes. That will get you the modality you want. :-P

I'd go with option 3--I'm always a fan of taking advantage of native input elements.

<tr ng-repeat="subscription in entities">
<td><input type="radio"
   ng-model="selection"
   name="subscriptionRadio"
   value="{{subscription}}"/>
</td> 
</tr>

本文标签: javascriptAngularJS single select between multiple checkboxStack Overflow