1

I'm filtering a list of objects in AngularJS using ng-repeat:

<tr ng-repeat="application in page.applications | filter: {DisplayName:page.ApplicationSearchValue}">
    {{application.DisplayName}}
</tr>

If the user puts an exclamation point as the first character in the search box, then Angular interprets that as a negation symbol. So !MyApplication returns all the applications except for MyAppliction.

I tried using a custom function as description in the Angular documentation for filter, but the exclamation point never finds its way into the function.

I found that the code is going through the following function in the AngularJS source code, which is basically enforcing that the exclamation point gets special treatment:

function deepCompare(actual, expected, comparator, matchAgainstAnyProp, dontMatchWholeObject) {
  var actualType = getTypeForFilter(actual);
  var expectedType = getTypeForFilter(expected);

  if ((expectedType === 'string') && (expected.charAt(0) === '!')) {
    return !deepCompare(actual, expected.substring(1), comparator, matchAgainstAnyProp);

      .....

My current "solution" is to change the filter object to:

filter: {DisplayName:(page.ApplicationSearchValue.indexOf('!') == 0 ? page.ApplicationSearchValue.substring(1) : page.ApplicationSearchValue)}

But it's only a matter of time until QA figures out that the problem would still occur if someone started the search box with !!.

Is there a common pattern for dealing with this situation?

3
  • Show us how you tried using a custom function. Commented Dec 5, 2016 at 17:02
  • ctrl.filterFunc = function(actual, expected) { expected = expected.indexOf('!') == 0 ? expected.substring(1) : expected; return actual.toLowerCase().indexOf(expected) != -1; } But the value of expected never included the exclamation point. Commented Dec 5, 2016 at 17:07
  • Don't pass a comparator. Pass a function as the unique argument of the filter. Make this function return true if the element should be accepted by the filter, and false otherwise. Commented Dec 5, 2016 at 17:10

1 Answer 1

1

I ended up using a directive I modified from this post. https://stackoverflow.com/a/15346236/2908576

MyApp.directive("noNegation", [function() {
    return {
        require: "ngModel",
        link: function(scope, element, attrs, ngModelController) {
            ngModelController.$parsers.push(function(data) {
                while (data.indexOf("!") == 0)
                    data = data.substring(1);
                return data;
            });
        }
    };
}]);

It ignores all exclamation points at the beginning of the input. That means that a search for !!!MyApplication still returns MyApplication, even though the exclamation points aren't in the name.

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

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.