Nick S.
Nick S.

Reputation: 418

Select multiple element affecting properties of the objects it's populated from

So I have this array people

people = [{name: "John",hair: false},{name: "James": hair: false}]

I have a select element with the multiple attribute that is populated from

 <select ng-model="people" multiple
         ng-options="person.hair as person.name for person in people">
 </select>

What I'm trying to achieve is when the user selects one or more items from this select element it will set the hair property of the selected item(s) to true.

Now what's happening is I select an item and it sets people to false, which makes sense. The select needs an ng-model for ng-options to work. If I set it to something else nothing gets changed on people

I've tried putting a function in ng-change and throwing the ng-model I set to it but that won't make the selection 'highlighted' in the select multiple element. I know there are more practical ways to do this but I'd like to figure out how to use the select multiple if I could.

Upvotes: 1

Views: 30

Answers (1)

georgeawg
georgeawg

Reputation: 48968

Here's one way to do it:

<select ng-model="hairyPersons" multiple
        ng-change="updatePeople(hairyPersons)"
        ng-options="person as person.name for person in people">
</select>
$scope.updatePeople = function(selects) {
    $scope.people.forEach(x => x.hair=false);
    selects.forEach(x => x.hair=true);
};

The ng-model variable needs to be different than the ng-options array.

The DEMO

angular.module("app",[])
.controller("ctrl", function($scope) {
  $scope.people = [
    {name: "John", hair: false},
    {name: "James", hair: false},
    {name: "Mary", hair: false},
    {name: "Fred", hair: false},
  ];
  $scope.updatePeople = function(selects) {
    $scope.people.forEach(x => x.hair=false);
    selects.forEach(x => x.hair=true);
  };
})
<script src="//unpkg.com/angular/angular.js"></script>
<body ng-app="app" ng-controller="ctrl">
     <select ng-model="hairyPersons" multiple
         ng-change="updatePeople(hairyPersons)"
         ng-options="person as person.name for person in people">
     </select>
     <div ng-repeat="p in people">
       {{p.name}} hair={{p.hair?'TRUE':false}}
     </div>
     <h3>hairyPersons</h3>
     <ol>
       <li ng-repeat="h in hairyPersons">{{h.name}}</li>
     </ol>
</body>


Another way to do it is with a list of checkboxes:

<div ng-repeat="p in people">
    <input type="checkbox" ng-model="p.hair">{{p.name}}<br>
</div>

The ng-model directives operate directly on objects in the people array.

All the unchecked boxes set hair: false; all the checked boxes set hair: true on their respective objects.

Upvotes: 1

Related Questions