I have created a plunker which explains what I am trying to achieve.
I have this array of objects $scope.menus
$scope.menus = [
{
name: 'Access',
submenu: [
{ name: 'User List'},
]
},
{
name: 'Organization',
submenu: [
{ name: 'City List'},
{ name: 'State List'},
{ name: 'Country List'},
]
},
{
name: 'Upload Logs',
submenu: [
{ name: 'Inventory Uploads'},
]
},
{
name: 'Bulk Logs',
submenu: [
{ name: 'Bulk Renewals'},
]
},
];
For the outside menu when searched, for eg like Access
or Organization
, only the searched item is returned.
But when inside menu is searched, for eg like City List
, in result I get all the other objects also including City List
.
I was expecting to get only City List
.
I have observed that for a nested array of objects, the filter is not working.
I may be wrong. Please guide me learning something new.
UPDATE
@Vivek solution worked. But now I am facing another issue. I have added some other arrays to my existing array.
As I type Bulk
or upload
in the search field, the submenu appears. But as soon as I typing the second word (for eg Bulk logs
or upload logs
), the submenu disappears.
If it had appeared when first word was typed, why did it disappeared when the second word was type.Why is it happening?
UPDATE Thank you all for your time and responses.
I have created a plunker which explains what I am trying to achieve. http://plnkr.co/edit/XAghimH20qwxQGjO42gP?p=preview
I have this array of objects $scope.menus
$scope.menus = [
{
name: 'Access',
submenu: [
{ name: 'User List'},
]
},
{
name: 'Organization',
submenu: [
{ name: 'City List'},
{ name: 'State List'},
{ name: 'Country List'},
]
},
{
name: 'Upload Logs',
submenu: [
{ name: 'Inventory Uploads'},
]
},
{
name: 'Bulk Logs',
submenu: [
{ name: 'Bulk Renewals'},
]
},
];
For the outside menu when searched, for eg like Access
or Organization
, only the searched item is returned.
But when inside menu is searched, for eg like City List
, in result I get all the other objects also including City List
.
I was expecting to get only City List
.
I have observed that for a nested array of objects, the filter is not working.
I may be wrong. Please guide me learning something new.
UPDATE
@Vivek solution worked. But now I am facing another issue. I have added some other arrays to my existing array.
As I type Bulk
or upload
in the search field, the submenu appears. But as soon as I typing the second word (for eg Bulk logs
or upload logs
), the submenu disappears.
If it had appeared when first word was typed, why did it disappeared when the second word was type.Why is it happening?
UPDATE Thank you all for your time and responses.
Share Improve this question edited Oct 8, 2018 at 4:34 Steve asked Oct 7, 2018 at 15:15 SteveSteve 5523 gold badges13 silver badges28 bronze badges 3- There are two exclusive filters in your code, they are not related and hence are pure pattern matches in their own array. I'd suggest you to remove the filter from the top ng-repeat. – Aragorn Commented Oct 7, 2018 at 18:18
- Checked it. If I do so, all the main menus are displayed, with the searched submenu if any. Is there a way to hide the upper menu if not submenu is found? – Steve Commented Oct 7, 2018 at 18:25
- Updated the answer, that might work for your use case, take a look. – Aragorn Commented Oct 7, 2018 at 19:04
3 Answers
Reset to default 4<input type="text" placeholder="Search text" ng-model="menuSearch"> <ul> <li ng-repeat="menu in menus | filter : menuSearch"> <span href="#">{{menu.name}}</span> <ul> <li ng-repeat="submenu in menu.submenu | filter : menuSearch"> <a href="#">{{submenu.name}}</a> </li> </ul> </li> </ul> </div>
you have to also write filter in sub menu ng-repeat like below,
<html>
<head>
<title>AngularJS ng-repeat filter</title>
<script src="https://ajax.googleapis./ajax/libs/angularjs/1.6.9/angular.js"></script>
<script src="script.js"></script>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body ng-app="app">
<div ng-controller="democontroller">
<input type="text" placeholder="Search text" ng-model="menuSearch">
<ul>
<li ng-repeat="menu in menus | filter : menuSearch">
<span href="#">{{menu.name}}</span>
<ul>
<li ng-repeat="submenu in menu.submenu | filter : menuSearch">
<a href="#">{{submenu.name}}</a>
</li>
</ul>
</li>
</ul>
</div>
</body>
</html>
Filter is only applied to the first loop, you need to add the filter on the submenu ng-repeat
like this:
<html>
<head>
<title>AngularJS ng-repeat filter</title>
<script src="https://ajax.googleapis./ajax/libs/angularjs/1.6.9/angular.js"></script>
<script src="script.js"></script>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body ng-app="app">
<div ng-controller="democontroller">
<input type="text" placeholder="Search text" ng-model="menuSearch">
<ul>
<li ng-repeat="menu in menus | filter : menuSearch">
<span href="#">{{menu.name}}</span>
<ul>
<li ng-repeat="submenu in menu.submenu | filter: menuSearch"> <!--Notice filter added here-->
<a href="#">{{submenu.name}}</a>
</li>
</ul>
</li>
</ul>
</div>
</body>
</html>
For your updated usecase, this might help, basically there is filter on the submenu, but the main menu is showed if the submenu is active or the search contains any of the text from menu:
<html>
<head>
<title>AngularJS ng-repeat filter</title>
<script src="https://ajax.googleapis./ajax/libs/angularjs/1.6.9/angular.js"></script>
<script src="script.js"></script>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body ng-app="app">
<div ng-controller="democontroller">
<input type="text" placeholder="Search text" ng-model="menuSearch">
<ul>
<li ng-repeat="menu in menus" ng-if="(menu.submenu | filter: menuSearch).length > 0 || (menu.name.includes(menuSearch))">
<span href="#">{{menu.name}}</span>
<ul>
<li ng-repeat="submenu in menu.submenu | filter : menuSearch">
<a href="#">{{submenu.name}}</a>
</li>
</ul>
</li>
</ul>
</div>
</body>
</html>