Bruno Henrique
Bruno Henrique

Reputation: 797

Angular filter to remove accents from the word inputed before applying the filter

I'm using the following filter to remove accents from the word inputed by the user on an input field, and then use the resulting string on the filter.

    .filter('removeAcentos', function(){
    return function (source) {
        var accent = [
            /[\300-\306]/g, /[\340-\346]/g, // A, a
            /[\310-\313]/g, /[\350-\353]/g, // E, e
            /[\314-\317]/g, /[\354-\357]/g, // I, i
            /[\322-\330]/g, /[\362-\370]/g, // O, o
            /[\331-\334]/g, /[\371-\374]/g, // U, u
            /[\321]/g, /[\361]/g, // N, n
            /[\307]/g, /[\347]/g, // C, c
        ],
        noaccent = ['A','a','E','e','I','i','O','o','U','u','N','n','C','c'];

        for (var i = 0; i < accent.length; i++){
            source = source.replace(accent[i], noaccent[i]);
        }

        return source;
    };
})

And the code in the view is:

    <input type="text" id="curso" name="curso" ng-model="ctrl.curso" validate>
    <ul>
        <li ng-repeat="curso in ctrl.arrayCursos | removeAcentos: ctrl.curso">
        ...
        </li>
    </ul>

However, I get the error "source is undefined" and I don't understand why. I also can't use a function inside my controller to be the filter since I'm going to use it in more controllers. I'd like to find where's the error on my code.

ctrl.curso is predefined when the user enters the page, so I don't understand the 'source is undefined' error, since ctrl.cursois always defined. ctrl.cursois get via $http request, in case it's relevant.

I was using |filter: ctrl.curso before, however know I need to convert ctrl.curso to a string without accents and filtering the list based on this string.

Just to clarify, I'm looking for to filter the array based on the word inputed by the user. However, first I want to convert this word to a string without accents and then apply the filter itself. For example, If the user types the word 'espécie', I want to filter based on the string 'especie'.

Upvotes: 2

Views: 8076

Answers (3)

nioKi
nioKi

Reputation: 1289

You need to chain filters. First, you need to remove the accent on the user input:

search | removeAcentos

Then you want to filter your array based on this new value:

filter: (search | removeAcentos)

Note the parenthesis to ensure filters are applied in the correct order.

Result of the updated ng-repeat:

<li ng-repeat="curso in ctrl.arrayCursos | filter: (search | removeAcentos)" />
        {{ curso }}
</li>

Link to Working JSFiddle

Upvotes: 5

vittore
vittore

Reputation: 17579

You are not using your filter right.

If you are going to filter collection - use filter for collection and return new collection where property will be filtered off of accents

If you want to use filter for display - don't apply filter to ng-repeat , apply it to your other binding, ie that is your new html:

 <li ng-repeat="curso in ctrl.arrayCursos ">
   {{   ctrl.curso | removeAcentos }} 
 </li>

Upvotes: 0

Mathew Berg
Mathew Berg

Reputation: 28750

Just add in the check:

.filter('removeAcentos', function(){
    return function (source) {
        if(!angular.isDefined(source)){ return; }
        var accent = [
            /[\300-\306]/g, /[\340-\346]/g, // A, a
            /[\310-\313]/g, /[\350-\353]/g, // E, e
            /[\314-\317]/g, /[\354-\357]/g, // I, i
            /[\322-\330]/g, /[\362-\370]/g, // O, o
            /[\331-\334]/g, /[\371-\374]/g, // U, u
            /[\321]/g, /[\361]/g, // N, n
            /[\307]/g, /[\347]/g, // C, c
        ],
        noaccent = ['A','a','E','e','I','i','O','o','U','u','N','n','C','c'];

        for (var i = 0; i < accent.length; i++){
            source = source.replace(accent[i], noaccent[i]);
        }

        return source;
    };
})

Upvotes: 0

Related Questions