Angular custom filter for complex object

I have $scope.usersone that I use to display a table, and I need to apply a filter with several parameters,

Here is the object $scope.users:

[
  {
    "login": "andres.un1@mail.com",
    "merchant": {
      "merchantId": 500095,
      "status": "ENABLED",
      "defaultAccountId": null,
      "accounts": {
        "500092": "ADMIN",
        "500178": "CONSULT",
        "500180": "ADMIN",
        "500182": "ADMIN",
        "500201": "ADMIN"
      }
    },    
    "name": "Carlos"    
  },
  {
    "login": "andres.un2@mail.com",
    "merchant": {
      "merchantId": 500095,
      "status": "DISABLED",
      "defaultAccountId": null,
      "accounts": {
        "500092": "CONSULT",
        "500178": "MANAGER",
        "500180": "ADMIN",
        "500182": "ADMIN",
        "500201": "ADMIN"
      }
    },
    "name": "Carlos Andres"
  },
  {
    "login": "cosme.fulanito@mail.com",
    "merchant": {
      "merchantId": 500095,
      "status": "DISABLED",
      "defaultAccountId": null,
      "accounts": {
        "500092": "CONSULT",
        "500178": "MANAGER",
        "500180": "ADMIN",
        "500182": "ADMIN",
        "500201": "ADMIN"
      }
    },
    "name": "Cosme"    
  }
]

In the filter, I pass another object from $scopeto filter the data, in this case $scope.searchParams, which I previously calculated in the directive.

$scope.searchParams:

[
  {'name':'Cosme'},
  {'login':'andres.un1@mail.com'},
  {'status':'ENABLED'},
  {'status':'DISABLED'},
  {'account':'267123'},
  {'account':'543987'},
  {'account':'544111'},
  {'account':'543987'}
]

As you can see, nameand loginare unique in the filter, but statusand accountcan have multiple values for use in the filter. Here is my approach to this, but I think it is very inefficient, it is also not complete, because it does not have a multiple filter function:

var secUser = function () {

  return function (input, list) {

    var out = [];

    var nameArr = [],
      loginArr = [],
      statusArr = [],
      profileArr = [],
      accountsArr = [];

    angular.forEach(list, function(filter){
      console.log(filter);
      if(filter.hasOwnProperty('name')){
        nameArr.push(filter.name);
      }
      if(filter.hasOwnProperty('login')){
        loginArr.push(filter.login);
      }
      if(filter.hasOwnProperty('status')){
        statusArr.push(filter.status);
      }
      if(filter.hasOwnProperty('account')){
        accountsArr.push(filter.account);
      }
      if(filter.hasOwnProperty('profile')){
        profileArr.push(filter.profile);
      }
    });

    angular.forEach(input, function(user){

      // no filters applied
      if(nameArr.length < 1 && loginArr.length < 1 &&
        statusArr.length < 1 && accountsArr.length < 1 &&
        profileArr.length < 1){
        out.push(user);
      }
      // filters to be applied
      else{
        if(nameArr.indexOf(user.name) > -1){
          out.push(user);
        }
        if(loginArr.indexOf(user.login) > -1){
          out.push(user);
        }
        if(statusArr.indexOf(user.merchant.status) > -1){
          out.push(user);
        }
      }

    });

    return out;
  };
};
//-- register filter
app.filter('secUser', secUser);

Finally, here is how I use fiter: <tbody ng-repeat="user in users | secUser:searchParams " class="table-striped">

¿ , , ? , .

+4
1

, - searchParams . , , - , - , :

$scope.searchParams = {
  'name': ['Cosme'],
  'login': ['andres.un1@mail.com'],
  'merchant.status' : ['ENABLED','DISABLED'],
  'merchant.accounts' : ['267123','543987 ','544111','543987'],
}

, . , -, . accounts 500092 CONSULT. , :

  • , . name
  • , . status
  • , . accounts

JsFiddle ( , )

var secUser = function () {
  return function (users, filters) {

    return users.filter(function(user){
      var match = false;

      angular.forEach(filters, function(filterValues, keyPath){
        if (match) return; // if we already found a match, don't continue searching

        // get the target based on the contents of the keypath
        var target = keyPath.split('.').reduce(function(object, key) {
          // get the next part of the path, if exists
          return object && object[key];
        }, user); // initial value is the user object

        if (target !== undefined){ // if the target exists for this item
          var values = []; // stores the values from the item to search against

          if(typeof target === "object") {
            values = Object.keys(target);            
          }
          else if (target.isArray) {
            values = target;
          } else {
            values = [target];
          }

          // check if any entry in values matches any entry of the filter values
          match = values.some(function (v) {
            return filterValues.indexOf(v) >= 0;
          });
        }
      });

      return match;
    });
  };
};
+1

Source: https://habr.com/ru/post/1654160/


All Articles