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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.