Charlie Charlie - 3 months ago 21
AngularJS Question

live search with angularJS with categories and tags

First of all I want to say I am following this fiddle for Advanced live-search with AngularJS, which is working great, but for my scenario I need to search for both catergories and category childs.

Example list:

$scope.names = [
{
name: "Kitchen",
tags: [
"Knife",
"Plate",
"Fork"
]
},
{
name: "Garage",
tags: [
"Car",
"Wrench",
]
}


Scenario Search:

Input Search:

knife


Result:

<li><b>Kitchen</b></li>
<li>Knife</li>


Scenario Search 2:

Input Search:

garage


Result:

<li><b>Garage</b></li>


I've tried to make some form of 'double'
ng-repeat
with something

like this:
ng-repeat="name in names || name in names
by separating categories from childs but then there will be problem with populating the list. I also don't know the correct operator for
AND
but I can imagine there is a lot better solution for this but I can't figure out how, Note that I am pretty new to AngularJS and JS.

Answer

To make filter works in both arrays, you have to create a custom filter.

See it working:

angular
  .module('app', [])
  .controller('MainCtrl', MainCtrl)
  .filter('customFilter', customFilter);

MainCtrl.$inject = ['$scope'];

function MainCtrl($scope) {

  $scope.names = [
    {
      name: "Kitchen",
      tags: [
        "Knife",
        "Plate",
        "Fork"
      ]
    }, 
    {
      name: "Garage",
      tags: [
        "Car",
        "Wrench",
      ]
    }
  ];
}

function customFilter() {
  return function(items, search) {
    if (!search) return items;
    
    search = search.toLowerCase();
    return items.filter(function(item) {
      return item.name.toLowerCase().indexOf(search) !== -1 || item.tags.filter(function(tag) {
        return tag.toLowerCase().indexOf(search) !== -1;
      }).length;
    });
  }
}
<!DOCTYPE html>
<html ng-app="app">

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

<body ng-controller="MainCtrl">
  <input type="text" placeholder="Search..." ng-model="search">
  <ul ng-repeat="obj in names | customFilter: search track by $index">
    <li><strong ng-bind="obj.name"></strong></li>
    <ul>
      <li ng-repeat="tag in obj.tags | filter: search track by $index" ng-bind="tag"></li>
    </ul>
  </ul>
</body>

</html>

I hope it helps.