1

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>

georgeawg
  • 48,608
  • 13
  • 72
  • 95
CMartins
  • 3,247
  • 5
  • 38
  • 53

1 Answers1

1

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.

timur
  • 14,239
  • 2
  • 11
  • 32