Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set a default value to ng-options (multiple select)

Tags:

angularjs

I wanted to set a default value to my ng-options by using ng-init, ng-model, etc. They didn't work at all. My code is following:

Angular

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

app.controller('fooController', function($scope){
    $scope.roles = [{id:1, name:"Administrator"}, {id:2, name: "Student"}];
    $scope.user.roles = $scope.roles[0];
});

HTML

<body data-ng-app="role" data-ng-controller="fooController">
  <select multiple class="form-control" data-ng-model="user.roles" data-ng-options="role.name for role in roles" required=""></select>
</body>

Here is my Plunkr. Any help would be appreciated.

like image 346
lvarayut Avatar asked Dec 08 '14 04:12

lvarayut


2 Answers

Update:

If you want to get directly to the reference used in this answer, here it is:

Reference: Initial Selection In AngularJS ng-options with track by

Here's what worked for me:

app.controller('fooController', function($scope){
    $scope.roles = [{id:1, name:"Administrator"}, {id:2, name: "Student"}];
    $scope.user = {};
    $scope.user.roles = [ $scope.roles[0] ];
});

There was an error in the plunk that user wasn't initialized, apart from this, Angular would compare every object in the ng-options array to every element in the ng-model array. JavaScript comparison not Angular comparison, comparing 2 objects even with same properties in JavaScript returns false (different objects).

Plunk: http://plnkr.co/edit/ccsAVvPACnN6Qzje7HcB?p=preview

.

Now, this is not ideal. Typically you want to correlate these based on ID or so, here's another way:

In HTML, use track by to tell AngularJS to compare IDs instead of entire objects:

  <select multiple class="form-control" 
    data-ng-model="user.roles" 
    data-ng-options="role.name for role in roles track by role.id" 
    required=""></select>

Then in your controller, you can use any object without actually being in the array:

app.controller('fooController', function($scope){
    $scope.roles = [{id:1, name:"Administrator"}, {id:2, name: "Student"}];
    $scope.user = {};
    $scope.user.roles = [ {id:1, name:"Administrator"} ];
});

Plunk: http://plnkr.co/edit/NKLXrwqwk36YfhBSXILN?p=preview

Note that I didn't even need the name property. It's just for making a proper object later, but it really isn't needed for matching now, try without it!

.

I wrote a detailed tutorial with an accompanying video on this initial selection problem and its variations. It's focused on single-select but multi-select is just using an array of objects instead of one object directly.

Check it out for more understanding -- highly recommended:

Initial Selection In AngularJS ng-options with track by

.

Let me know in comments if you are still struggling with this.

like image 98
Meligy Avatar answered Oct 10 '22 11:10

Meligy


if your model is like $scope.user.roles = [1]; then your ng-options should be like this,

  data-ng-options="role.id as role.name for role in roles"

this will select only the ID

if you do like data-ng-options="role.name for role in roles" then your model should be like

$scope.user.roles = [{id:1, name:"Administrator"}];

because this will select the whole object

and in your controller

$scope.user = {}; //this line should be add

because your trying to access a roles property of user but there is no user object defined, this will also occur a error

here is the Updated Plunker


here is the updated plunker1 plunker2 for your case of ng-options

you can use ng-init here. please check.

like image 35
Kalhan.Toress Avatar answered Oct 10 '22 09:10

Kalhan.Toress