angularjs custom filter to check for values inside a data array

后端 未结 5 937
野趣味
野趣味 2020-12-02 02:34

I have two filters which filter the data according to the queue key in the data. Here is my code :

相关标签:
5条回答
  • 2020-12-02 03:12

    I solved the problem by adding another forEach loop to go through the queuearr when queue is inside an array:

    var app =angular.module('app', []);
    
    app.controller('mainController', function($scope) {
        // Data object
       $scope.servers = [
        {name:'ServerA', queuearr:[{'queue' :'111'},{'queue' :'456'}]},
        {name:'Server7', queuearr:[{'queue' :'111'}]},
        {name:'Server2', queuearr:[{'queue' :'456'}]},
        {name:'ServerB', queuearr:[{'queue' :'456'}]},
    ];
    
        // Filter defaults
        $scope.Filter = new Object();
        $scope.Filter.queue = {'PAV':'111',
                                'UAT':'456'
                            };
       
    });
    
    // Global search filter
    app.filter('searchFilter',function($filter) {
            return function(items,searchfilter) {
    //console.log(items);
                 var isSearchFilterEmpty = true;
                  angular.forEach(searchfilter, function(searchstring) {   
                      if(searchstring !=null && searchstring !=""){
                          isSearchFilterEmpty= false;
                      }
                  });
            if(!isSearchFilterEmpty){
                    var result = [];  
                    angular.forEach(items, function(item) {  
    
                        var isFound = false;
                         angular.forEach(item.queuearr, function(z) {
    //console.log(item.queue);     
    		    angular.forEach(z, function(term,key) {
    //console.log(z);
    //console.log(item.queue);                         
                             if(term != null &&  !isFound){
                                 term = term.toString();
                                 term = term.toLowerCase();
                                    angular.forEach(searchfilter, function(searchstring) {  
    //console.log(searchfilter);    
                                        searchstring = searchstring.toLowerCase();
                                        if(searchstring !="" && term.indexOf(searchstring) !=-1 && !isFound){
                                           result.push(item);
                                            isFound = true;
                                        }
                                    });
    
                             }
                                });
     });
                           });
                return result;
            }else{
            return items;
            }
        }
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.4/angular.min.js"></script>
    <div ng-app="app">
        <div  ng-controller="mainController">
            <label>show 111</label>
            <input  type="checkbox" ng-model="Filter.queue.PAV" ng-true-value='"111"'  ng-false-value='""' />&nbsp;
            <label>show 456</label>
            <input  type="checkbox" ng-model="Filter.queue.UAT" ng-true-value='"456"'  ng-false-value='""' />&nbsp;
          
            <hr />
            <table width="100%" cellpadding="5">
                <tr>
                    <th>Name</th>
                   
                   
                </tr>
                <tr ng-repeat="server in servers | searchFilter:Filter.queue">
                    <td>{{server.name}}</td>
                   
                   
                </tr>
            </table>
        </div>
    </div>

    Now it's working perfectly

    0 讨论(0)
  • 2020-12-02 03:14

    If you want to filter $scope.servers with the values of the queue you can try this. Hope this helps.

    const servers = [
        {name:'ServerA', queuearr:[{'queue' :'111'}]},
        {name:'Server7', queuearr:[{'queue' :'111'}]},
        {name:'Server2', queuearr:[{'queue' :'456'}]},
        {name:'ServerB', queuearr:[{'queue' :'456'}]},
    ];
    
    const itemsToCheck = { 'PAV':'111', 'UAT':'426' };
    
    const filter = (arr, itemsToCheck) => arr.filter((item) => {
    
        for (let v of Object.values(itemsToCheck)) {
    
            const found = item.queuearr.find(({ queue }) => queue === v);
    
            if (found) return true;
        }
    
        return false;
    });
    
    console.log(filter(servers, itemsToCheck));

    0 讨论(0)
  • 2020-12-02 03:22

    I have modified your snippet as per your given array. Its working fine as per your need.

    var app = angular.module('app', []);
    
    app.controller('mainController', function($scope) {
      // Data object
      /*
      $scope.servers = [{
          name: 'ServerA',
          queue: '111'
        },
        {
          name: 'Server7',
          queue: '111'
        },
        {
          name: 'Server2',
          queue: '456'
        },
        {
          name: 'ServerB',
          queue: '456'
        },
      ];
      */
      $scope.servers = [
        {name:'ServerA', queuearr:[{'queue' :'111'}]},
        {name:'Server7', queuearr:[{'queue' :'111'}]},
        {name:'Server2', queuearr:[{'queue' :'456'}]},
        {name:'ServerB', queuearr:[{'queue' :'456'}]},
    ];
    
      // Filter defaults
      $scope.Filter = new Object();
      $scope.Filter.queue = {
        'PAV': '111',
        'UAT': '456'
      };
    
    });
    
    // Global search filter
    app.filter('searchFilter', function($filter) {
      return function(items, searchfilter) {
        var isSearchFilterEmpty = true;
        angular.forEach(searchfilter, function(searchstring) {
          if (searchstring != null && searchstring != "") {
            isSearchFilterEmpty = false;
          }
        });
        if (!isSearchFilterEmpty) {
          var result = [];
          angular.forEach(items, function(item) {
            var isFound = false;
            angular.forEach(item.queuearr, function(term, key) {
              if (term.queue != null && !isFound) {
                term.queue = term.queue.toString();
                term.queue = term.queue.toLowerCase();
                angular.forEach(searchfilter, function(searchstring) {
                  searchstring = searchstring.toLowerCase();
                  if (searchstring != "" && 
                  term.queue.indexOf(searchstring) != -1 &&
                  !isFound) {
                    result.push(item);
                    isFound = true;
                  }
                });
              }
            });
          });
          return result;
        } else {
          return items;
        }
      }
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.3/angular.min.js"></script>
    <div ng-app="app">
      <div ng-controller="mainController">
        <label>show 111</label>
        <input type="checkbox" ng-model="Filter.queue.PAV" ng-true-value='"111"' ng-false-value='"!111"' />&nbsp;
        <label>show 456</label>
        <input type="checkbox" ng-model="Filter.queue.UAT" ng-true-value='"456"' ng-false-value='"!456"' />&nbsp;
    
        <hr />
    
        <table width="100%" cellpadding="5">
          <tr>
            <th>Name</th>
    
            <th>Queue</th>
    
          </tr>
          <tr ng-repeat="server in servers | searchFilter:Filter.queue">
            <td>{{server.name}}</td>
    
            <td>{{server.queuearr[0].queue}}</td>
    
          </tr>
        </table>
      </div>
    </div>

    0 讨论(0)
  • 2020-12-02 03:30

    you have some conditions to change in the Angular.forEach take a look at the solution.

    ServerB shows up in both searchs

    var app = angular.module('app', []);
    
    app.controller('mainController', function($scope) {
      // Data object
      $scope.servers = [{
          name: 'ServerA',
          queue: '111'
        },
        {
          name: 'Server7',
          queue: '111'
        },
        {
          name: 'Server2',
          queue: '456'
        },
        {
          name: 'ServerB',
          queue: '456',
          queuearr: [{
            queue: '456'
          }, {
            queue: '111'
          }]
        },
      ];
    
      // Filter defaults
      $scope.Filter = new Object();
      $scope.Filter.queue = {
        'PAV': '111',
        'UAT': '456'
      };
    
    });
    
    // Global search filter
    app.filter('searchFilter', function($filter) {
      return function(items, searchfilter) {
        var isSearchFilterEmpty = true;
        angular.forEach(searchfilter, function(searchstring) {
          if (searchstring != null && searchstring != "") {
            isSearchFilterEmpty = false;
          }
        });
        if (!isSearchFilterEmpty) {
          var result = [];
          angular.forEach(items, function(item) {
            var isFound = false;
            angular.forEach(item, function(term, key) {
              // change here to check for arrays
              if (term || Array.isArray(term) && !isFound) {
                // use JSON.stringify here
                term = JSON.stringify(term);
                term = term.toLowerCase();
                angular.forEach(searchfilter, function(searchstring) {
                  searchstring = searchstring.toLowerCase();
    
                  if (searchstring != "" && term.indexOf(searchstring) != -1 && !isFound) {
                    result.push(item);
                    isFound = true;
                  }
                });
              }
            });
          });
          return result;
        } else {
          return items;
        }
      }
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.3/angular.min.js"></script>
    <div ng-app="app">
      <div ng-controller="mainController">
        <label>show 111</label>
        <input type="checkbox" ng-model="Filter.queue.PAV" ng-true-value='"111"' ng-false-value='"!111"' />&nbsp;
        <label>show 456</label>
        <input type="checkbox" ng-model="Filter.queue.UAT" ng-true-value='"456"' ng-false-value='"!456"' />&nbsp;
    
        <hr />
    
        <table width="100%" cellpadding="5">
          <tr>
            <th>Name</th>
    
            <th>Queue</th>
    
          </tr>
          <tr ng-repeat="server in servers | searchFilter:Filter.queue">
            <td>{{server.name}}</td>
    
            <td>{{server.queue}}</td>
    
          </tr>
        </table>
      </div>
    </div>

    0 讨论(0)
  • 2020-12-02 03:30

    I think you can do it like this. It is not clear what it is exactly what you want to do because your code is overly complicated and badly aligned.

    app.filter('searchFilter',function($filter) {
      return function(items, searchfilter) {
          const terms = Object.values(searchfilter).map(
              (val)=>val.toLowerCase(),
          );
          return items.filter((item) =>
              item.queuearr.some((q) => terms.includes(q.queue.toLowerCase())),
          );
      };
    }
    
    0 讨论(0)
提交回复
热议问题