HaveSpacesuit
HaveSpacesuit

Reputation: 4004

Use Exclamation Point as First Character with AngularJS Filter

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?

Upvotes: 1

Views: 816

Answers (1)

HaveSpacesuit
HaveSpacesuit

Reputation: 4004

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.

Upvotes: 1

Related Questions