Search code examples
javascriptangularjsjsonng-options

How do I create a "select all" option from an ng-options dropdown that automatically selects all of the options?


I would like to populate my ng-options dropdown with an option that when selected, will select all possible options in the dropdown. Part of the problem is I do not how to programmatically select options that are being populate from an existing JSON object in this specific case. How do I create a function that iterates over the current object, then inserts them into a function that programmatically selects them when this specific object is selected?

Code

Here is the example JSON object that the dropdown is populated from:

accounts = [
{
   "Id": 2,
   "DisplayName": "Bob",
},
{
   "Id": 2,
   "DisplayName": "George",
},
{
   "Id": 2,
   "DisplayName": "Michael",
},
]

Here is my HTML dropdown code:

 <div class="form-group">  
    <label for="audience" class="col-sm-2 control-label">Audience</label>  
    <div class="col-sm-8">      
       <select id="audience" ng-model="newAnnouncement.audience"
               ng-options="accountsData.DisplayName as accountsData.DisplayName for accountsData in accounts"
               multiple >
          <option value="">All</option>
       </select>
    </div>
       <div class="col-sm-2 space">      
    </div>
 </div>

In my component.js file:

(function () {
'use strict';
angular.module('adminPanel')
    .component('adminAnnouncements', {
        templateUrl: 'app/admin-panel/admin-announcements/admin-announcements.html',
        controller: [
            '$scope', 'arcService',
            function adminAnnouncementsController($scope, arcService) {
                var my = this;
                $scope.accounts = [];

                my.$onInit = () => {
                    $scope.loadAccounts();
                }

                $scope.newAnnouncement = {
                };
            }
        ]
    }
);}
)();

Trials & Thoughts

I have looked into trying to clone the JSON object, then set it as the value of the

<option value="">All</option>.

So when all is selected, it would highlight all the options. But after doing some looking around I realized you can't exactly clone a JSON object. Another Idea I had was to manually populate the all object with all the account objects with a javascript .push() function, but I want this function to be dynamic, so when a new accounts object is created, I do not need to come back and manually add the accounts object to the all object.


Solution

  • Add a click handler on the option:

    <option value="" ng-click="$ctrl.all($event)">All</option>
    

    That selects all the choices:

    this.all = function(ev) {
        this.audience = this.accounts.reduce((a,i)=>(a.push(i.DisplayName),a),[]);
    };
    

    The DEMO

    angular.module("app",[])
    .controller("ctrl",function() {
      this.audience = [];
      this.accounts = [
        {"Id": 2,"DisplayName": "Bob",},
        {"Id": 2,"DisplayName": "George",},
        {"Id": 2,"DisplayName": "Michael",},
      ];
      this.all = function(ev) {
        this.audience = this.accounts.reduce((a,i)=>(a.push(i.DisplayName),a),[]);
      };
    })
    <script src="//unpkg.com/angular/angular.js"></script>
    <body ng-app="app" ng-controller="ctrl as $ctrl">
        <select id="audience" ng-model="$ctrl.audience"
                ng-options="o.DisplayName as o.DisplayName for o in $ctrl.accounts"
                multiple >
          <option value="" ng-click="$ctrl.all($event)">All</option>
        </select>
        <br>{{$ctrl.audience}}
    </body>