I\'m adding a simple sort on a page. The idea is to search products. These products are written in spanish language and has accents. For example: \'Jamón\'.
Here is
Here is a slightly enhanced version (not counting the extra foreign characters it searches for, of course) of the above. I put it straight into my controller and it allowed me to search all the data that I wanted to search. Thanks Bernardo for your input into this!
Hope it helps somebody out.
function removeAccents(value) {
return value
.replace(/á/g, 'a')
.replace(/â/g, 'a')
.replace(/é/g, 'e')
.replace(/è/g, 'e')
.replace(/ê/g, 'e')
.replace(/í/g, 'i')
.replace(/ï/g, 'i')
.replace(/ì/g, 'i')
.replace(/ó/g, 'o')
.replace(/ô/g, 'o')
.replace(/ú/g, 'u')
.replace(/ü/g, 'u')
.replace(/ç/g, 'c')
.replace(/ß/g, 's');
}
$scope.ignoreAccents = function (item) {
if ($scope.search) {
var search = removeAccents($scope.search).toLowerCase();
var find = removeAccents(item.name + ' ' + item.description+ ' ' + item.producer+ ' ' + item.region).toLowerCase();
return find.indexOf(search) > -1;
}
return true;
};
Check here for solutions to filter a list of objects and search keywords in every property of every object. It also maintain angular like search and also search with/ without accent characters.
Following is the filter definition:-
// ignore accents filter
$scope.ignoreAccents = function (item) {
if (!$scope.search) return true;
var objects = [];
var jsonstr = JSON.stringify(item);
var parsejson = JSON.parse(jsonstr);
var searchterm = $scope.search.replace(/[!#$%&'()*+,-./:;?@[\\\]_`{|}~]/g, ''); // skip replace if not required (it removes special characters)
objects = getNoOfResults(parsejson, searchterm);
return objects.length > 0;
};
You'll need to create a filter function (or a full filter). This is the simplest thing that could possibly work:
HTML
<div ng-app ng-controller="Ctrl">
<input type="text" ng-model="search">
<ul>
<li ng-repeat="name in names | filter:ignoreAccents">{{ name }}</li>
</ul>
</div>
Javascript
function Ctrl($scope) {
function removeAccents(value) {
return value
.replace(/á/g, 'a')
.replace(/é/g, 'e')
.replace(/í/g, 'i')
.replace(/ó/g, 'o')
.replace(/ú/g, 'u');
}
$scope.ignoreAccents = function(item) {
if (!$scope.search) return true;
var text = removeAccents(item.toLowerCase())
var search = removeAccents($scope.search.toLowerCase());
return text.indexOf(search) > -1;
};
$scope.names = ['Jamón', 'Andrés', 'Cristián', 'Fernán', 'Raúl', 'Agustín'];
};
jsFiddle here.
Please notice that this only works for arrays of strings. If you want to filter a list of objects (and search in every property of every object, like Angular does) you'll have to enhance the filter function. I think this example should get you started.
JavaScript has a neat function for this, called localeCompare
, where you can specify sensitivity = base
, an option that makes it treat á
and a
as equivalent, but it is not widely supported. I think your only option is to create a filter function wherein you normalise both strings manually (replacing ó
with o
and so on) and compare the results.
The method, proposed by @Michael Benford has a big disadvantage: it is a stateful filter. This practice is strongly discouraged by angular. Plus, the method doesn’t work with deep arrays and objects.
I prefer to extend the standard angular filter:
HTML:
<div ng-app ng-controller="Ctrl">
<input type="text" ng-model="search">
<ul>
<li ng-repeat="person in people | filter: search : searchFn">{{ person.names }} {{ person.surnames }}</li>
</ul>
</div>
Javascript:
function Ctrl($scope) {
$scope.people = [{names: 'Jose', surnames: 'Benítez'}, {names: 'José María', surnames: 'Núñez Rico'}, {names: 'Rodrigo', surnames: 'Núñez'}];
$scope.searchFn = function(actual, expected) {
if (angular.isObject(actual)) return false;
function removeAccents(value) {
return value.toString().replace(/á/g, 'a').replace(/é/g, 'e').replace(/í/g, 'i').replace(/ó/g, 'o').replace(/ú/g, 'u').replace(/ñ/g, 'n');
}
actual = removeAccents(angular.lowercase('' + actual));
expected = removeAccents(angular.lowercase('' + expected));
return actual.indexOf(expected) !== -1;
}
}