4

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.

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. 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? Commented Oct 7, 2018 at 18:25
  • Updated the answer, that might work for your use case, take a look. Commented Oct 7, 2018 at 19:04

3 Answers 3

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>
Sign up to request clarification or add additional context in comments.

Comments

3

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.com/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>

13 Comments

It works, but some new issues have come. I have updated the plunker. Please help in resolving the issue.
because of Log word is not present in your submenu
you should have to make to search boxes one for menu and second for submenu it will solve your issue
Can't do that sir, I need the single box to search both the menus. Can there be some custom filter made to resolve such issue where if nothing found in submenu, whole submenu is displayed, would this be possible?
for that you have to write your own custom filter
|
2

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.com/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.com/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>

3 Comments

That fixed it, but now I am facing other issue. Posting it now. I have updated the PLUNKER.
I have updated the plunker with new issue and array. Please help in resolving the issue.
I will revert after I have checked. Thank you for response. Good night

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.