简体   繁体   中英

AngularJS Filter array with a nested ng-repeat

I have this nested list that I would like to filter based in searchKey Input that contain a array of strings (kendo multiselector). The filter field should be the {{ child.name }} field and the filter result should be applied to the main element on the first ng-repeat item in colection.items

I have no idea how can I filter this array of values against the array of keywords from the kendo input. I try this similar case but with no success. AngularJS filter based on array of strings? . Any help will be appreciated.

<div ng-app="ngApp">
<div ng-controller="ngAppController">
    <div id="filtering">                    
        <input id="searchKey" type="text" placeholder="Search keys" ng-model="listSearch" />
    </div>
    <ul id="allItems" infinite-scroll="colection.nextPage()"
        infinite-scroll-distance="0"
        infinite-scroll-disabled='colection.busy || colection.finished'>
        <li ng-repeat="item in colection.items | filter:listSearch"
            ng-show="colection.items.length > 0"
            class="block-grid-item">
            <a href="javascript: void(0);" data-detail="{{ item.Id }}">
                <div class="imageWrap" style="background-image:url({{ item.thumb }});">

                    <div class="filetypeContainer"><span>{{ item.fileFormatIdentifier }}</span></div>
                    <ul>
                        <li ng-repeat="child in item.categories" style="list-style: none; display: inline-block;">
                            <code style="font-size:11px;">{{ child.name }} </code>
                        </li>
                    </ul>
                    <div class="infoContainer">i</div>
                </div>
            </a>
        </li>
    </ul>

Given I've got your problem statement correctly, it doesn't really matter what you filter on, as long as you can somehow inspect an item (and, look into its categories ) and tell if it's a match for you. As the answer you found points out, you can make a filter (for clarity call it multiSelectFilter )

<div ng-app="ngApp">
<div ng-controller="ngAppController">
    <div id="filtering">                    
        <select kendo-multi-select k-options="selectOptions" k-ng-model="listSearch"></select> <!-- note custom kendo directives. See more documentation here: https://demos.telerik.com/kendo-ui/multiselect/angular  -->
    </div>
    <ul id="allItems">
        <li ng-repeat="item in colection.items | multiSelectFilter:listSearch"
            ng-show="colection.items.length > 0"
            class="block-grid-item">
            <a href="javascript: void(0);" data-detail="{{ item.Id }}">
                <div class="imageWrap" style="background-image:url({{ item.thumb }});">

                    <div class="filetypeContainer"><span>{{ item.fileFormatIdentifier }}</span></div>
                    <ul>
                        <li ng-repeat="child in item.categories" style="list-style: none; display: inline-block;">
                            <code style="font-size:11px;">{{ child.name }} </code>
                        </li>
                    </ul>
                    <div class="infoContainer">i</div>
                </div>
            </a>
        </li>
    </ul>
  </div>
</div>
var app = angular.module('ngApp', ['kendo.directives']);

app.controller("ngAppController", function($scope){
      $scope.listItems = [{name:'Baseball'}, {name:'Basketball'}, {name:'Cricket'}, {name:'Field Hockey'}, {name:'Football'}, {name:'Table Tennis'}, {name:'Tennis'}, {name:'Volleyball'}];
      $scope.colection = {items: [
       {id:0, thumb: '0', fileFormatIdentifier :'1', categories: [{name:'Baseball'}, {name:'Basketball'}]},
        {id:1, thumb: '1', fileFormatIdentifier :'2', categories: [{name:'Cricket'}]},
        {id:2, thumb: '2', fileFormatIdentifier :'3', categories: [{name:'Field Hockey'}, {name:'Football'}]},
        {id:3, thumb: '3', fileFormatIdentifier :'4', categories: [{name:'Tennis'}, {name:'Volleyball'}]},
      ]                           
                          };
      $scope.listSearch = [];
      $scope.selectOptions = {
            placeholder: "Select products...",
            valuePrimitive: true,
            dataTextField: "name",
            dataValueField: "name",
            autoBind: false,
            dataSource: $scope.listItems
        };
});   

app.filter('multiSelectFilter', function() {
    return function(items, listSearch) {
        return items.filter(function(item) {
            if(listSearch.length === 0) 
              return true; // suppose we don't want to filter if no condition was set          
            var result = false
            result = item.categories.some((child) => {
              return listSearch.some((listSearchItem) => { 
                return (child.name === listSearchItem); // return true if we've got a match
            });
            });      
          return result;
        });
    };
});

Here's the working code pen: https://codepen.io/timur_kh/pen/xxGVzLv .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM