Фильтрация элементов в Awesomplete по умолчанию реализована как поиск подстроки без строгого ограничения позиции совпадения. Это означает, что совпадение может находиться в любой части строки, и элемент будет показан пользователю даже в случае, если вводимые символы встречаются не в начале значения.
Поведение определяется функцией Awesomplete.filter,
которая принимает два аргумента: текст элемента списка и текущее
значение ввода. В стандартной реализации используется проверка через
регулярное выражение или indexOf, но без ограничения
позиции начала строки.
Внутренняя логика библиотеки сводится к следующему принципу:
true включает элемент в выпадающий
список.Упрощённый вид стандартной фильтрации:
Awesomplete.filter = function (text, input) {
return text.toLowerCase().indexOf(input.toLowerCase()) > -1;
};
Такой подход обеспечивает гибкий поиск, но не гарантирует совпадение с началом строки.
Для реализации строгого поведения, при котором элементы отображаются
только если они начинаются с введённого текста, используется проверка
позиции 0.
Ключевая идея:
Реализация:
Awesomplete.filter = function (text, input) {
return text.indexOf(input) === 0;
};
В этом случае:
"JavaScript" будет показан при вводе
"Ja";"JavaScript" не будет показан при вводе
"va".В реальных интерфейсах важно учитывать регистр символов. Без нормализации поведение становится чувствительным к регистру, что снижает удобство поиска.
Расширенная версия фильтрации с учётом регистра:
Awesomplete.filter = function (text, input) {
const value = text.toLowerCase();
const query = input.toLowerCase();
return value.indexOf(query) === 0;
};
Здесь выполняется:
Альтернативный способ — применение регулярного выражения с якорем
начала строки ^.
Awesomplete.filter = function (text, input) {
const escaped = input.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
const pattern = new RegExp('^' + escaped, 'i');
return pattern.test(text);
};
Преимущества подхода:
i;Недостатки:
Awesomplete поддерживает списки не только из строк, но и из объектов, где отображаемое значение может отличаться от внутреннего.
Пример структуры:
[
{ label: "JavaScript", value: "js" },
{ label: "Java", value: "java" }
]
Фильтрация по началу строки должна учитывать поле
label:
Awesomplete.filter = function (text, input) {
const value = text.label || text;
return value.toLowerCase().indexOf(input.toLowerCase()) === 0;
};
Такой подход позволяет:
При использовании динамических данных важно учитывать источник списка. Например, при загрузке данных с сервера:
new Awesomplete(input, {
list: []
});
После получения данных:
fetch("/api/languages")
.then(r => r.json())
.then(data => {
awesomplete.list = data;
});
Фильтрация по началу строки автоматически применяется ко всем новым
элементам после переопределения Awesomplete.filter.
Фильтрация часто используется совместно с
Awesomplete.sort, которая определяет порядок отображения
элементов.
При строгой фильтрации по началу строки сортировка может быть упрощена:
Awesomplete.sort = function (a, b) {
return a.localeCompare(b);
};
Или полностью отключена логика «похожести», если важен только префикс.
Особенность реализации заключается в том, что при пустом вводе:
true для всех
элементов;При необходимости можно изменить это поведение:
Awesomplete.filter = function (text, input) {
if (!input) return false;
return text.toLowerCase().indexOf(input.toLowerCase()) === 0;
};
Теперь список не раскрывается без ввода.
При работе с большим объёмом данных фильтрация по началу строки имеет преимущество:
Дополнительно можно уменьшить количество операций:
Awesomplete.filter = (text, input) => {
const len = input.length;
return text.slice(0, len).toLowerCase() === input.toLowerCase();
};
Такой вариант избегает поиска подстроки и работает через сравнение фиксированного фрагмента.
При использовании нелатинских алфавитов важно учитывать:
Расширенный вариант:
Awesomplete.filter = function (text, input) {
const normalize = str =>
str.normalize("NFKD").toLowerCase();
return normalize(text)
.indexOf(normalize(input)) === 0;
};
Это повышает предсказуемость фильтрации в многоязычных интерфейсах.