Search code examples
javascriptangularjsng-options

ng-options filtering based on a property


Basically i am java developer recently switched to coding in javascript(AngularJs) so i am comnpletely new to javascript/AngularJS. While I was coding I came across a case wherein if I had to show say as in ex: set of fruits only/Vegetables only or both based on the drop down selected what i am doing currently is having a "fruitNVeg " array which holds all items and having a temp variable "currentItems" which at any instance filters out the required items like Fruit only/Vegtable only/both based on the items selected.

Now my question is Are there any ways wherein i could use "fruitNVeg" itself in the HTML and say show only the items whose "show" property is set to true. i.e.,To get same functionality without using the extra variable "currentItems".

Also please optimize my current logic if possible in terms No. of lines I am fed up of creating 2 arrays(complete+filtered) everywhere :-(

FruitsController.js
     $scope.fruitNVeg = [
                       { id : 1, name : "mango" , show : true , cat : "F"},
                       { id : 2, name : "orange", show : true , cat : "F"},
                       { id : 3, name : "tomato", show : true , cat : "F"},
                       { id : 4, name : "brinjal",show : false , cat : "V"},  
                       { id : 4, name : "potato", show : false , cat : "V"},
                       { id : 4, name : "ginger", show : false , cat : "V"}, 
                       ];

   $scope.selectList = [ 
                         {id:1, name  : "Fruits Only" },
                         {id:2, name  : "Vegetable Only" },
                         {id:3, name  : "Fruits & Vegetable" },
                        ];
    $scope.selectedItem = $scope.selectList[0];                  
    $scope.currentItems = angular.copy($scope.fruitNVeg,$scope.currentItems);
    $scope.selItem = $scope.currentItems[0];

    $scope.onChangeSelecList = function (){
        if(selectedItem.name == "Fruits Only"){
           //Use $filter to populate $scope.currentItems  with fruits only items
        } else if(selectedItem.name == "Vegetable Only"){
          //Use $filter to populate $scope.currentItems  with vegetables only items
        } else {
           $scope.currentItems = angular.copy($scope.fruitNVeg,$scope.currentItems);
        }
        $scope.selItem = $scope.currentItems[0];
    };

FruitDemo.Html
     <label> Please Select what to show <label>
     <select ng-model="selectedItem" ng-options="list.name for list in selectList" ng-change="onChangeSelecList()" name="listDropDown" id="listDropDown"></select>
     <select ng-model="selItem" ng-options="item.name for item in currentItems"  name="itemDropDown" id="itemDropDown"></select>

Solution

  • You can watch selected option and can accordingly change currentItem list.ngChange expression is used to evaluate the change in input value not for option value change.

    $scope.$watch("selectedItem", function(i) {
      $scope.currentItems.length = 0;
      if (i.id === 1) {
        angular.forEach($scope.fruitNVeg, function(val, key) {
          if (val.cat === 'F') {
            $scope.currentItems.push(val);
          }
        });
      } else if (i.id === 2) {
        angular.forEach($scope.fruitNVeg, function(val, key) {
          if (val.cat === 'V') {
            $scope.currentItems.push(val);
          }
        });
      } else {
        $scope.currentItems = $scope.fruitNVeg;
      }
      $scope.selItem = $scope.currentItems[0];
    });
    

    Jsfiddle Example