Search code examples
angularjsangularjs-filter

How do filter two (only visually) joined expressions in AngularJS 1.5.11


Scenario: I have a array of items, that each item has properties (model,id),

$scope.arrayOfItems = [{
                         model : 'L_',
                         id : 01
                       },
                       {
                         model : 'L_',
                         id : 2323
                       },
                       {
                         model : 'L_',
                         id : 434
                       }
                    ];

For each item, both of these properties are merged to form a item Label. I'm trying filter the two VISUALLY merged expressions

{{::item.model}}{{::item.id}}

model = 'L_';
id    = 03;

So the result would be L_03

If I wish to search for the item Label 'L_2323' in the input field and type 'L_' followed by the id, all the list items disappear.

I want to be able to type 'L_2323' and have the corresponding list item being displayed

I understand that I can loop through and merge all the models and id's and put inside a array in the controller and display each item of that array inside the main item's loop, but that seems like a wasteful solution and I'm trying to solve the problem in a more pragmatic way

I have added a codepen of this bug
Codepen


Solution

  • Simply write a custom filter that scans the array for a match of model + id together. Here is a quick demo of what it can look like:

    var app = angular.module('myApp', []);
    app.filter('myFilter', function() {
      return function(arrayOfItems, input) {
        var res = [];
        if (input) {
          for (var i = 0; i < arrayOfItems.length; i++) {
            var item = arrayOfItems[i];
            if ((item.model + item.id).match(input)) { // match
              res.push(item);
            }
          }
          // don't return an empty array if nothing was found
          return (res.length > 0) ? res : arrayOfItems; 
        }
        return arrayOfItems; // default (no input given)
      };
    });
    
    app.controller('namesCtrl', function($scope) {
      $scope.arrayOfItems = [{
          model: 'L_',
          id: 01
        },
        {
          model: 'L_',
          id: 2323
        },
        {
          model: 'L_',
          id: 434
        }
      ];
    });
    <!DOCTYPE html>
    <html>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
    
    <body>
      <div ng-app="myApp" ng-controller="namesCtrl">
    
        <span>Filter your search : 
          <input type="text" ng-model="searchFilter">
          {{searchFilter}}
        </span>
        
        <hr>
    
        <div ng-repeat="item in arrayOfItems | myFilter: searchFilter">
          {{item.model}}{{item.id}}
        </div>
      </div>
    </body>
    </html>