基于我之前的question,我试图在社区的帮助下构建一个搜索过滤器功能,即使用户在搜索输入字段中输入非拉丁字符(在这种情况下,该字符也是如此)瑞典字母)。
这是我到目前为止所拥有的:
var langMap = {
'a' : 'å',
'a' : 'ä',
'o' : 'ö'
}
$('#search-items-box').keyup(function(){
var valThis = $(this).val().toLowerCase();
var filteredWord = valThis.split('').map(function(letter){
if (langMap[letter]) {
return langMap[letter];
}
return letter;
}).join('');
if(filteredWord == ""){
$('.itemsList .m3-item').show();
} else {
$('.itemsList .m3-item').each(function(){
var text = $(this).text().toLowerCase();
(text.indexOf(filteredWord) == 0) ? $(this).show() : $(this).hide();
});
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<input placeholder="Search Me" id="search-items-box" type="text" />
<div class="itemsList">
<div class="m3-item">Orånge</div>
<div class="m3-item">Banäna</div>
<div class="m3-item">Potatö</div>
</div>
问题是搜索无法正常进行。如果尝试键入三个单词,您会注意到结果没有显示。
答案 0 :(得分:1)
第一个条件是,如果满足此条件,则在每次击键时都要更改字符输入:
if (langMap[letter]) {
return langMap[letter];
现在,当您键入'b'时,香蕉将出现在搜索中,因为'b'不是langMap数组的一部分,因此不会被修改。它搜索以'b'开头的任何单词,搜索结果为'Banäna'
但是,一旦您输入“ a”,香蕉便不再存在,因为它已转换为“å”。结果,它正在搜索“bå”,该结果将返回零结果(按预期)。
另一方面,您稍后还会在langMap数组中遇到另一个问题:
var langMap = {
'a' : 'å',
'a' : 'ä',
'o' : 'ö'
};
您有一个键'a'
,它定义了两个不同的值。其中一个值将永远无法访问。
根据我们的讨论,这是我建议的解决方案:
langMap
的键和值将比较后的文本转换为拉丁字符
var langMap = {
"å":"a",
"ä":"a",
"ö":"o"
}
$('#search-items-box').keyup(function(){
var valThis = $(this).val().toLowerCase();
var filteredWord = getLatinWord(valThis);
if(filteredWord == ""){
$('.itemsList .m3-item').show();
} else {
$('.itemsList .m3-item').each(function(){
var text = $(this).text().toLowerCase();
text = getLatinWord(text);
(text.indexOf(filteredWord) === 0) ? $(this).show() : $(this).hide();
});
}
});
function getLatinWord(word){
return word.split('').map(function(character){
if (langMap[character]) {
return langMap[character];
}
return character;
}).join('');
}
答案 1 :(得分:0)
在这里,我提出了一种以数据为中心的方法。这是使您的可能匹配满足需求的问题。根据您的规范,标准化的单词应具有以下特征:
这是在函数normalizeWord
中完成的。
其余的代码创建一个dictionary
来绑定原始
这个词是标准化的表示形式。 filter
函数返回
数据集中与输入匹配的原始单词的列表。
实际上,将代码绑定到DOM时会出现一些不匹配的情况,因为这种方法实际上适用于给定的数据集。在现实生活中,我只是从过滤后的列表中重建匹配项的HTML表示,而不是显示和隐藏已经存在的DOM元素。
$(function() {
var langMap = {
'å' : 'a',
'ä' : 'a',
'ö' : 'o'
};
var words = [
'Orånge',
'Banäna',
'Potatö'
];
// Create normalized words
// The map with the original and normalized word
var dictionary = {};
// Normalization
words.forEach(function(w) {
var word = normalizeWord(w);
dictionary[word] = w;
});
function normalizeWord(word) {
for (key in langMap) {
word = word.toLowerCase()
.replace(new RegExp(key, 'g'), langMap[key]);
}
return word;
}
function filter(word) {
var possibleMatch = normalizeWord(word);
var result = [];
for (normalizedWord in dictionary) {
if (normalizedWord.indexOf(possibleMatch) === 0) {
result.push(dictionary[normalizedWord]);
}
}
return result;
}
// Test
var results = [
'b -> ' + filter('b'),
'bs -> ' + filter('bs'),
'baNana -> ' + filter('baNana'),
'Potatö -> ' + filter('Potatö')
]
console.log(results);
// Binding to the DOM
$('#search-items-box').keyup(function() {
var value = $(this).val();
var matches = filter(value);
if (matches.length === 0) {
$('.itemsList .m3-item').show();
return;
}
$('.itemsList .m3-item').each(function() {
var $this = $(this),
value = $this.html();
if (matches.indexOf(value) > -1) {
$this.show();
} else {
$this.hide();
}
});
});
});