0

I need to create a filter in angularjs

My data looks something like this:

[{
    name: 'account1', 
    accounts: [
      {
        name: 'account2', 
        accounts: []
      }, 
      {
        name: 'account3', 
        accounts: [
          {
            name: 'account4',
            accounts: []
          }
        ]
      }
    ]
 }]

I need the filter return the full object if I use account4 for the search text. Or just the first 2 levels if I use account2 etc.

I have searched all over but cant find anything like this and have no idea where to start.

4
  • It's not clear what your expected results are, can you provide your filter criteria, and expected object output? Commented Aug 31, 2015 at 22:36
  • Like I said. If the filter criteria is "account4" I would expect the full object. If the search criteria is "account2" I would expect just the top 2 levels of the object. Commented Aug 31, 2015 at 22:48
  • What is a level of an object? Commented Aug 31, 2015 at 23:20
  • account1 is in the first level, 2 and 3 and in the second, and 4 is in the 3rd. An account is the object and each account can have more account objects in an array. That is what i refer to as levels. Commented Aug 31, 2015 at 23:36

2 Answers 2

1

You'll need to create a custom filter to do what you're requesting. A controller filter will only allow you to provide an expression to include or exclude an ng-repeat item.

A custom filter will allow you to modify the model dynamically. You can splice the json object accordingly.

I'll provide an example when I'm back in in front of a pc.

Sign up to request clarification or add additional context in comments.

Comments

1

I got it figured out finally. Here is the custom filter I created in case anyone else finds it useful:

.filter('accountsFilter', function() {

  return function(items, searchStr) {

    function filterAccounts(account, str) {

      //if account name matches
      if (account.name && account.name.toLowerCase().indexOf(str.toLowerCase()) > -1) {

        //expand parent account
        if (account.accounts && account.accounts.length > 0) account.expand = true;

        //return account
        return account;

      } else

      //account name doesnt match. check sub accounts
      if (account.accounts && account.accounts.length > 0) {

        //has accounts
        var fa = [];
        angular.forEach(account.accounts, function(act, k) {
          var a = filterAccounts(act, str);

          //if account was returned
          if (a !== false) {

            //add account to filtered accounts
            fa.push(act);
          }   
        });

        //add accounts to parent account
        account.accounts = fa;

        //if there are sub-accounts
        if (fa.length > 0) {

          //make sure account is expanded to show sub accounts
          if (account.accounts && account.accounts.length > 0) account.expand = true;

          //return account
          return account;

        //no sub accounts left
        } else {

          //check and return if main account matches
          return filterAccounts(account, str);
        }

      //no matches              
      } else {
        return false;
      }
    }

    //copy accounts list to prevent original being altered
    var accounts = angular.copy(items);
    var filtered = [];

    //loop through accounts list
    angular.forEach(accounts, function(account) {

      //check if current account matches
      var a = filterAccounts(account, searchStr.name);
      if (a) {

        //add to filtered list
        filtered.push(a);
      }
    });
    return filtered; 
  };
})    

Comments

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.