2

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'.

2
  • You need to add a check if source is defined and is string source = source || "" in the beginning. Commented Aug 12, 2015 at 18:18
  • I tried this, however It gives an error I described on the answer below. The weird thing is that source is never undefined, since ctrl.curso is a predefined string when the page loads. Commented Aug 12, 2015 at 18:33

3 Answers 3

5

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

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

7 Comments

I tried this, but the console gives the error source.replace is not a function
Even the JSFiddle is not working ? Which browser are you using ?
Ouch, now I see the confusion. I don't want to convert all the strings on the array to strings without accents. I want to filter the array based on user inputed string but removing the accents from this string.
Example: the user enters the word 'espécie', but I want to filter based on the word 'especie'
Ah, yes, it seems that none of us did understood that. You rework your question. I'm trying to update my answer.
|
0

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; }; }) 

4 Comments

I added the check, but now there is a 'source.replace is not a function' when I focus on the input field or type any letter. I'll provide some more details in the question.
You want to do your filter removeAcentos: ctrl.curso AFTER the ng-repeat (in some other element) not trying to filter your array of ctrl.arrayCursos
Sorry, I don't get it. My intention is to filter the ctrl.arrayCursos with the input from the user. I was using | filter: ctrl.curso instead, and It worked, but know I need this filter to convert the word entered by the user to a string without accents before filtering.
Console log source and see what it spits out. It's an array. It's your array ctrl.arrayCursos. I highly recommend you read over some tutorials and do the course on the main angular page as this is a basic concept.
0

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> 

1 Comment

I'm clearly doing some very wrong. As the answer below, the error source.replace is not a function appears.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.