Norfeldt
Norfeldt

Reputation: 9678

How to get list of checkboxes to behave like a dropdown with AngularJS

Dropdowns are fine to get a radio button behaviour and hide a long list... But I never liked them.. They require the user to click in order to see the list and their style don't match the page.

I would like to find a more dynamic way using angular.

How do I display a list of checkboxes and hide all unchecked checkboxes once a checkbox is checked? Unchecking the checkbox should then display all checkboxes again...

I tried the following, but without any luck.

<ul>
  <li ng-repeat="album in albums | filter: '{{selected}}' ">
   <input type="checkbox" ng-model="selected" ng-value="{{album.name}}" />
   </li>
</ul>

Upvotes: 0

Views: 350

Answers (2)

Norfeldt
Norfeldt

Reputation: 9678

I found a solution using the controller.

Controller

albums = [  
     {  
        "id":"1",
        "name":"Album 1"
     },
     {  
        "id":"2",
        "name":"Album 2"
     },
     {  
        "id":"3",
        "name":"Album 3"
     }
  ];

$scope.display = ( new Array(albums.lenght) ).fill( true );

var onlyOneTrue = function(){
    if ( $filter("filter")( $scope.display , true).length == 1 ){
      return true;
    } else {
      return false;
    }
  }

$scope.changed = function(index) {
  if ( onlyOneTrue() ) {
    $scope.display.fill( true );
  } else {
    $scope.display.fill(false)[index] = true;
  }
}

HTML

<ul>
  <li ng-repeat="album in albums' ">
   <input type="checkbox" ng-show="display[$index]" ng-click="changed($index)"> 
     {{album.name}}
   </input>
   </li>
</ul>

Upvotes: 0

developer033
developer033

Reputation: 24884

If I understand your question well, it should work:

(function() {
  "use strict";
  angular.module('app', [])
    .controller('mainCtrl', function($scope) {
      var vm = this;

      vm.albums = [  
         {  
            "id":"1",
            "name":"Album 1"
         },
         {  
            "id":"2",
            "name":"Album 2"
         },
         {  
            "id":"3",
            "name":"Album 3"
         }
      ];

      vm.selected = {};
      vm.disable = {};

      $scope.$watch(function() {
          return vm.selected;
        },
        function(newVal, oldVal) {
          var newValIndex = 0;
          for (var key in newVal) {
            if (newVal[key]) {
              newValIndex = parseInt(key);
            }
          }
          for (var i = 0; i < vm.albums.length; i++) {
            vm.disable[i] = i === newValIndex ? false : newVal[newValIndex.toString()];
          }
        }, true);
    });
})();
<!DOCTYPE html>
<html ng-app="app">

<head>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.min.js"></script>
</head>

<body ng-controller="mainCtrl as main">
  <ul>
    <li ng-repeat="album in main.albums">
      <input type="checkbox" id="album{{$index}}" value="{{album}}" ng-model="main.selected[$index]" ng-disabled="main.disable[$index]">
      <label for="album{{$index}}" ng-bind="album.name"></label>
    </li>
  </ul>
  <pre ng-bind="main.selected | json"></pre>
</body>

</html>

I hope it helps.

Upvotes: 1

Related Questions