angularjs搜索并忽略西班牙语字符

时间:2013-08-10 17:43:23

标签: angularjs

我在页面上添加了一个简单的排序。我们的想法是搜索产品。这些产品以西班牙语编写并具有重音。例如:'Jamón'。

这是我的代码:

<div class="form-inline">
  <label>Search</label>
  <input type="text" ng-model="q"/>
</div>

<div ng-repeat="product in products_filtered = (category.products | filter:q | orderBy:'name')">
           ....
</div>

我唯一的问题是你必须输入“Jamón”才能找到产品“Jamón”。我想要的是更灵活,如果用户输入“Jamon”,结果必须包括“Jamón”。

如何使用角度过滤器进行搜索并忘记重音?有什么想法吗?

提前致谢。

5 个答案:

答案 0 :(得分:8)

您需要创建过滤功能(或完整过滤器)。这是最简单的事情:

<强> 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

请注意,这仅适用于字符串数组。如果要过滤对象列表(并在每个对象的每个属性中搜索,如Angular那样),则必须增强过滤器功能。我想这个例子应该让你开始。

答案 1 :(得分:3)

JavaScript有一个很好的功能,称为localeCompare,您可以在其中指定sensitivity = base,这个选项可以将áa视为等效,{{ 3}}。我认为您唯一的选择是创建一个过滤函数,其中您手动规范化两个字符串(将ó替换为o,依此类推)并比较结果。

答案 2 :(得分:2)

以上是一个稍微增强的版本(当然不包括它搜索的额外外来字符)。我把它直接放到我的控制器中,它允许我搜索我想要搜索的所有数据。感谢Bernardo对此的投入!

希望能帮助别人。

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

答案 3 :(得分:2)

@Michael Benford提出的方法有一个很大的缺点:它是一个有状态的过滤器。这种做法是strongly discouraged by angular。此外,该方法不适用于深度数组和对象。

我更喜欢扩展标准角度滤镜:

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

答案 4 :(得分:1)

检查here以获取解决方案,以过滤对象列表并在每个对象的每个属性中搜索关键字。它还保持像搜索一样的角度,也可以搜索带/不带重音字符。

以下是过滤器定义: -

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