0

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.

georgeawg
  • 48,608
  • 13
  • 72
  • 95
  • If you want to make the migration path to Angular 2+ easier, avoid injecting $scope in components and use `$ctrl` for the Model. – georgeawg Dec 27 '18 at 23:41
  • How about using on-click on that option item to handle the logic inside the controller. In the controller on-click logic, you can check if the option All is selected or not and then set the selected property of all the elements accordingly. Check similar question here. https://stackoverflow.com/questions/27451954/angular-checkboxes-select-all-functionality-with-only-one-box-selected-initial – Harshini Prakash Dec 27 '18 at 23:41
  • @georgeawg yeah! I have just learned about that in a previous post I made. I see you marked my question as a duplicate. I looked at the question you referenced and it is not using a select input. So are you saying there is no way to accomplish a "select all" function in a select input? Instead to just use the check boxes? The other problem is that example is using an object created in the component, but my object is pre-created and pulled out of a database, so I am unsure on how to add the "selected=true/false" key/value pair to my object in order to make that example work. Thanks again! – GuyWithGlasses Dec 28 '18 at 17:06

1 Answers1

0

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>
georgeawg
  • 48,608
  • 13
  • 72
  • 95
  • This is it! Thank you very much. Had to debug a bit to get it to work for my use, but in that I learned a lot. I appreciate your patience and time. Cheers! – GuyWithGlasses Dec 28 '18 at 18:57
  • You're welcome. Frankly I think checkboxes provide a better user experience. ` – georgeawg Dec 28 '18 at 19:07
  • The problem I have with checkboxes is how much real estate a list of them would take up. Also, with the select input, I can ShiftHold + Lclick to select a range of options rather than individually click each one. The app I am building is more utilitarian. I am always open to suggestions if you have a counter to this? – GuyWithGlasses Dec 28 '18 at 19:25