При работе с библиотекой Choices.js поведение поиска по умолчанию
реализовано через Fuse.js и ориентировано на нечувствительное к регистру
сопоставление строк. Это означает, что значения Apple,
apple и APPLE рассматриваются как
эквивалентные при фильтрации списка. В ряде сценариев требуется
противоположное поведение — строгая регистрозависимость, при которой
различие между заглавными и строчными буквами влияет на результаты
поиска.
Внутри Choices.js поиск основан на Fuse.js, который по умолчанию приводит строки к нормализованному виду:
searchFieldsПример стандартного поведения:
const choices = new Choices('#select', {
searchEnabled: true,
searchChoices: true
});
При таком подходе поиск строки apple вернёт:
без различий по регистру.
Регистрозависимая фильтрация используется в случаях:
API,
Api, api)ABc123 ≠
abc123)Fuse.js, используемый внутри Choices.js, изначально оптимизирован для человеко-ориентированного поиска. Поэтому:
caseSensitive в стандартной
интеграции ChoicesfuseOptionsОсновной способ добиться строгого сравнения — настройка Fuse.js через
fuseOptions.
const choices = new Choices('#select', {
searchEnabled: true,
searchChoices: true,
fuseOptions: {
ignoreLocation: true,
threshold: 0.0,
ignoreFieldNorm: true,
minMatchCharLength: 1,
isCaseSensitive: true
}
});
isCaseSensitive
true различаются A и
athreshold
0.0 превращает поиск в почти точное совпадениеignoreLocation
Если поведение Fuse.js недостаточно предсказуемо, используется кастомная логика фильтрации.
В Choices.js можно переопределить механизм поиска через
callbackOnCreateTemplates и внутреннюю фильтрацию данных,
либо через предварительную нормализацию списка.
const choices = new Choices('#select', {
searchEnabled: true,
searchChoices: true,
callbackOnSearch: function(value, choice) {
return choice.value.includes(value);
}
});
Здесь используется стандартная строковая проверка
includes, которая уже является регистрозависимой.
Дополнительный способ — отказ от автоматической нормализации входных данных.
const items = [
{ value: 'Apple', label: 'Apple' },
{ value: 'apple', label: 'apple' }
];
При таком подходе различие сохраняется на уровне данных, а не алгоритма поиска.
Choices позволяет ограничить поля поиска через
searchFields, что влияет на поведение фильтрации:
const choices = new Choices('#select', {
searchEnabled: true,
searchChoices: true,
searchFields: ['label', 'value']
});
При комбинировании с кастомным Fuse можно добиться строгого контроля над тем, какие именно строки участвуют в сравнении.
Для сложных систем применяется гибридный подход:
const choices = new Choices('#select', {
searchEnabled: true,
searchChoices: true,
fuseOptions: {
threshold: 0,
ignoreLocation: true,
ignoreFieldNorm: true,
isCaseSensitive: true
},
callbackOnSearch: (value, choice) => {
return choice.label.indexOf(value) !== -1;
}
});
Регистрозависимый поиск влияет не только на равенство строк, но и на подстроки:
App не совпадает с appApple не совпадает с appleAPP совпадает только с точным APPЭто важно учитывать при длинных списках, где пользовательский ввод может отличаться по стилю набора.
При отключении fuzzy-логики в Choices.js поведение становится более линейным:
Одновременное использование fuseOptions и
callbackOnSearch может приводить к неожиданным результатам,
так как сначала применяется Fuse, затем кастомная логика.
Если данные заранее приведены к нижнему регистру, включение case-sensitive режима не даёт эффекта.
Choices не позволяет полностью удалить Fuse без кастомной переработки поискового механизма.
В системах, где регистр критичен, Choices.js обычно используется не как единственный слой логики, а как UI-компонент:
Такой подход исключает зависимость от внутреннего поведения Fuse.js и делает регистрозависимость предсказуемой.