Andrej Kaurin
Andrej Kaurin

Reputation: 11642

Angularjs select multiple options from object

Trying to select multiple options in angularjs regarding to object values

Here is a code:

myapp.controller('myctrl', [
        '$scope',
        function ($scope) {
            $scope.query = {
                Statuses: {
                    Draft: true,
                    Live: true,
                    Pending: true,
                    Archived: false,
                    Deleted: false
                }
            };


        }
    ]);​

And html

<div ng-controller="myctrl">
<select multiple>
    <option value="Draft" ng:model="query.Statuses['Draft']">Draft</option>
    <option value="Pending" ng:model="query.Statuses.Pending">Pending</option>
    <option value="Live" ng:model="query.Statuses.Live">Live</option>
    <option value="Archived" ng:model="query.Statuses.Archived">Archived</option>
    <option value="Deleted" ng:model="query.Statuses.Deleted">Deleted</option>
</select>

    {{query | json}}
</div>

(Non)working sample on jsfiddle​

http://jsfiddle.net/andrejkaurin/h9fgK/

Upvotes: 12

Views: 46474

Answers (4)

enigment
enigment

Reputation: 3616

Just to point out, IMO multiple select elements are a UI interaction evil. Touch anything without remembering to hold down modifier keys, which some users don't know about, and you lose the whole selection. Especially bad if there enough options that they're not all visible, then you can't even tell when you're dropping an existing selection. Multiple checkboxes are a much better way to represent the same possible options and current selection. A container's worth of them can be made scrollable, effectively similar to a multi-select with more options than size. (Not an answer I know...)

Upvotes: 6

Mark Rajcok
Mark Rajcok

Reputation: 364677

Using a model for statuses ($scope.statuses), and ng-options to iterate over them:

function MyCtrl($scope) {
    $scope.statuses = [ 'Draft', 'Pending', 'Live', 'Archived', 'Deleted' ];
    $scope.selectedStatuses = [ 'Pending', 'Live' ];
}​

.

<select ng-model="selectedStatuses" multiple ng-options="status for status in statuses">
</select>

Upvotes: 14

Andrej Kaurin
Andrej Kaurin

Reputation: 11642

Here is an alternate to blesh solution

app.controller('MainCtrl', function($scope) {

  $scope.query = {
      Statuses: ["Pending","Live"]
  };
});

And select

<select multiple ng:model="query.Statuses" >
      <option value="Draft">Draft</option>
      <option value="Pending">Pending</option>
      <option value="Live">Live</option>
      <option value="Archived">Archived</option>
      <option value="Deleted">Deleted</option>
  </select>
  {{query | json}}

Working sample is here:

http://plnkr.co/edit/bCLnOo

Upvotes: 6

Ben Lesh
Ben Lesh

Reputation: 108471

You're trying to use a select multiple like a checkbox list, which is a little strange. Multi-selects output an array. You can't put ng-model on an option tag like that, it goes on the select itself. So since the select will output an array of values, you'll need to loop through the values and update the nodes in your scope.

Here's a plunk demonstrating the code

And here's the code:

JS

function inArray(x, arr) {
  for(var i = 0; i < arr.length; i++) {
    if(x === arr[i]) return true;
  }
  return false;
}

app.controller('MainCtrl', function($scope) {
   $scope.query = {
                Statuses: {
                    Draft: true,
                    Live: true,
                    Pending: true,
                    Archived: false,
                    Deleted: false
                }
            };
  $scope.selectionsChanged = function(){
    for(var key in $scope.query.Statuses) {
      $scope.query.Statuses[key] = inArray(key, $scope.selectedValues);
    }
  };
});

HTML

<select multiple ng-model="selectedValues" ng-change="selectionsChanged()">
    <option value="Draft" ng-selected="query.Statuses.Draft">Draft</option>
    <option value="Pending" ng-selected="query.Statuses.Pending">Pending</option>
    <option value="Live" ng-selected="query.Statuses.Live">Live</option>
    <option value="Archived" ng-selected="query.Statuses.Archived">Archived</option>
    <option value="Deleted" ng-selected="query.Statuses.Deleted">Deleted</option>
</select>
<br/>
    {{query | json}}

I hope that helps.

Upvotes: 12

Related Questions