如何为 typeahead 数据集中的每个 datumtokenizer 设置唯一的 minLength
How to set unique minLength for each datumtokenizer in typeahead dataset
背景:
我正在使用 typeahead.js 向用户显示搜索建议。我希望用户希望能够看到基于我数据集的 both "title" & "diff" 的建议。我遇到的问题是,当标题和差异字段重叠时,可能会导致一些混乱的结果。
在此图片中,您可以看到活动查询是 "Ea",并且 typehead 正在为标题 "Earthbound" 和差异 "Easy" 提供建议。我不喜欢这个结果,我希望少于 3 个字符的查询只从 "title" 字段中提取。
问题:
如何为数据集中的每个 datumtokenizer 设置唯一的 minLength?因此建议从第一个字符开始的标题中提取,并且建议不会从 "diff" 开始提取,直到查询至少有 3 个字符。
代码:
var games = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('title', 'diff'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
prefetch: 'https://api.myjson.com/bins/ss93y'
);
$('.basic .typeahead').typeahead({
hint: false,
highlight: true,
minLength: 1,
limit: 5,
}, {
name: 'games',
display: 'title',
source: games,
templates: {
header: '<h3 class="games-header">Games</h3>'
}
});
JS Fiddle:
https://jsfiddle.net/n3my5r8u/
鉴于您需要的自定义级别,我建议您实现自己的数据获取和 substringMatcher 函数,而不是使用 Bloodhound。我的解决方案基于 official documentation
中的第一个示例
fetch('https://api.myjson.com/bins/ss93y').then(result => {
return result.json();
}).then(games => {
var substringMatcher = (query, cb) => {
var normalizedQuery = query.toLowerCase();
if (normalizedQuery.length < 3) {
/* if query shorter than 3 chars, filter on title only */
return cb(games.filter(game => game.title.toLowerCase().includes(normalizedQuery)));
} else {
/* if query at least 3 chars, filter on title or diff */
return cb(games.filter(game => game.title.toLowerCase().includes(normalizedQuery) || game.diff.toLowerCase().includes(normalizedQuery)));
}
}
$('.basic .typeahead').typeahead({
hint: false,
highlight: true,
minLength: 1,
limit: 50,
}, {
name: 'games',
display: 'title',
source: substringMatcher,
templates: {
header: '<h3 class="games-header">Games</h3>'
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://twitter.github.io/typeahead.js/releases/latest/typeahead.bundle.js"></script>
<div class="basic">
<input class="typeahead" type="text" placeholder="Search">
</div>
请注意,我将查询和游戏数据集都转换为小写,因此您的搜索将不区分大小写。
背景:
我正在使用 typeahead.js 向用户显示搜索建议。我希望用户希望能够看到基于我数据集的 both "title" & "diff" 的建议。我遇到的问题是,当标题和差异字段重叠时,可能会导致一些混乱的结果。
在此图片中,您可以看到活动查询是 "Ea",并且 typehead 正在为标题 "Earthbound" 和差异 "Easy" 提供建议。我不喜欢这个结果,我希望少于 3 个字符的查询只从 "title" 字段中提取。
问题:
如何为数据集中的每个 datumtokenizer 设置唯一的 minLength?因此建议从第一个字符开始的标题中提取,并且建议不会从 "diff" 开始提取,直到查询至少有 3 个字符。
代码:
var games = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('title', 'diff'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
prefetch: 'https://api.myjson.com/bins/ss93y'
);
$('.basic .typeahead').typeahead({
hint: false,
highlight: true,
minLength: 1,
limit: 5,
}, {
name: 'games',
display: 'title',
source: games,
templates: {
header: '<h3 class="games-header">Games</h3>'
}
});
JS Fiddle: https://jsfiddle.net/n3my5r8u/
鉴于您需要的自定义级别,我建议您实现自己的数据获取和 substringMatcher 函数,而不是使用 Bloodhound。我的解决方案基于 official documentation
中的第一个示例fetch('https://api.myjson.com/bins/ss93y').then(result => {
return result.json();
}).then(games => {
var substringMatcher = (query, cb) => {
var normalizedQuery = query.toLowerCase();
if (normalizedQuery.length < 3) {
/* if query shorter than 3 chars, filter on title only */
return cb(games.filter(game => game.title.toLowerCase().includes(normalizedQuery)));
} else {
/* if query at least 3 chars, filter on title or diff */
return cb(games.filter(game => game.title.toLowerCase().includes(normalizedQuery) || game.diff.toLowerCase().includes(normalizedQuery)));
}
}
$('.basic .typeahead').typeahead({
hint: false,
highlight: true,
minLength: 1,
limit: 50,
}, {
name: 'games',
display: 'title',
source: substringMatcher,
templates: {
header: '<h3 class="games-header">Games</h3>'
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://twitter.github.io/typeahead.js/releases/latest/typeahead.bundle.js"></script>
<div class="basic">
<input class="typeahead" type="text" placeholder="Search">
</div>
请注意,我将查询和游戏数据集都转换为小写,因此您的搜索将不区分大小写。