0

I have the following code in my controller:

$scope.filteredTransactions = $scope.invoiceTransactionsObject.transactions.concat(); // make a copy of the initial array
if ($scope.searchTerm.message)
{
    var search = $scope.searchTerm.message;
    $scope.filteredTransactions = $filter('filter')($scope.filteredTransactions, ({ message: search } || { item: search }));
}

I want to be able to filter by typing some value and search either in the message column or item column. According to How to filter multiple values (OR operation) in angularJS it should work, but it doesn't and if I type something that can be found in the message, it works, but when I type something from the item, it returns empty array.

Do you see where is my mistake?

Community
  • 1
  • 1
Naomi
  • 718
  • 1
  • 9
  • 28

1 Answers1

2

Update Deleted irrelevant/mistaken initial answer

Since you're applying $filter inside a JS script, and it doesn't use any of the advanced features of $filter, I'd switch over to the JS-native method of filtering an array:

$scope.filteredTransactions = $scope.invoiceTransactionsObject.transactions.concat(); // make a copy of the initial array
if ($scope.searchTerm.message)
{
    var search = $scope.searchTerm.message;
    $scope.filteredTransactions = $scope.filteredTransactions.filter(function (trans) {
return trans.message.toLowerCase().indexOf(search) >= 0 || trans.item.toLowerCase().indexOf(search) >= 0;
    });
}

...assuming that $filter is case-insensitive and matches anywhere in the string. If that's not the functionality of $filter and/or not what you want, you'd adjust the code accordingly.

Kevin
  • 5,874
  • 3
  • 28
  • 35
  • I don't have $scope.searchTerm.item at all. My search input control has the following ng-model : searchTerm.message. Originally it was just searchTerm and also had filter in the HTML and it worked fine. But then I wanted to move the filtering in the code to be done by a button. So, I want to search for whatever I type in the search control in 2 columns of my array – Naomi Jun 03 '15 at 18:35
  • To be clear, I have several columns in the filteredTransactions object including message and item column. The name of the input search control should not matter, I believe. I just want the filter to be applied to either of these 2 columns and not other columns of my array. – Naomi Jun 03 '15 at 18:39
  • 1
    OK, my mistake. Sorry, I don't have a solution that makes use of what you have, but I can see where the solution in the linked SO question wouldn't work when you bring it from an Angular expression (as the asker is talking about) into JS code. The "||" in your example is evaluated in JavaScript, so it just checks if { message: search } is true, which it is. The second half ({ item: search }) isn't even evaluated in that context. – Kevin Jun 03 '15 at 18:44
  • If that's not clear, the unspoken assumption is that anything expression-like that appears in a binding expression in a view/template is an *Angular* expression, which is similar to JS but not the same. The asker appears to be assuming something like `
    `. The syntax and what you can do inside JS w/filters is different, in a way I have no experience with.
    – Kevin Jun 03 '15 at 18:49
  • I can try going back to just searching for the input, e.g. $scope.filteredTransactions = $filter('filter')($scope.filteredTransactions, search) although I'd really like to have a solution of searching in 2 of my columns and not all columns (as some are not shown in the grid). – Naomi Jun 03 '15 at 18:51
  • 1
    Your updated answer works perfectly for me after I fixed mistyped toLowerCase(). Thanks again, I was thinking in that same direction but was not sure how to implement the filtering. – Naomi Jun 03 '15 at 19:14
  • 1
    I'm pretty sure there's a way to do what you were trying, with $parse() or $eval(), but I don't know how to do it. Just mentioning so that anyone reading this in the future doesn't get the wrong idea; IMO using native JS inside the controller is easier to read/maintain, so I would do it this way even if I knew how to do it the other way :) – Kevin Jun 03 '15 at 19:18