Awesomplete — лёгкая JavaScript-библиотека для реализации автодополнения в текстовых полях ввода. Она создаёт выпадающий список подсказок на основе введённых пользователем символов и позволяет быстро выбирать подходящие варианты из заранее подготовленного или динамически загружаемого набора данных.
Основная идея библиотеки заключается в минимализме. В отличие от крупных UI-фреймворков, Awesomplete содержит только необходимую функциональность для построения автокомплита и практически не навязывает структуру приложения.
Типичный процесс работы выглядит следующим образом:
Подключение состоит из двух компонентов:
Пример подключения через локальные файлы:
<link rel="stylesheet" href="awesomplete.css">
<input id="search">
<script src="awesomplete.js"></script>
После загрузки библиотеки можно создавать экземпляры автодополнения.
const input = document.querySelector("#search");
const awesomplete = new Awesomplete(input, {
list: [
"JavaScript",
"TypeScript",
"Python",
"PHP",
"Java"
]
});
После инициализации поле начинает автоматически отображать совпадающие варианты.
Awesomplete поддерживает декларативный подход.
Достаточно указать специальный класс:
<input
class="awesomplete"
data-list="JavaScript,TypeScript,Python,PHP">
После загрузки страницы библиотека самостоятельно создаст экземпляр компонента.
Такой подход удобен для небольших проектов и статических страниц.
Более гибким считается программный способ инициализации.
const input = document.querySelector("#city");
const autocomplete = new Awesomplete(input);
После создания объекта данные можно задавать отдельно.
autocomplete.list = [
"Almaty",
"Astana",
"Karaganda",
"Shymkent"
];
Преимущество заключается в возможности динамически изменять источник данных в любой момент работы приложения.
Самый распространённый вариант.
new Awesomplete(input, {
list: [
"Apple",
"Samsung",
"Xiaomi",
"Huawei"
]
});
Каждый элемент массива представляет отдельную подсказку.
Разрешается передавать строку.
new Awesomplete(input, {
list: "HTML,CSS,JavaScript,TypeScript"
});
Библиотека автоматически преобразует строку в набор элементов.
Awesomplete может использовать стандартный HTML-элемент
datalist.
<input id="language">
<datalist id="languages">
<option>JavaScript</option>
<option>Python</option>
<option>Java</option>
<option>Go</option>
</datalist>
new Awesomplete("#language", {
list: "#languages"
});
Подобный вариант позволяет хранить данные непосредственно в HTML-разметке.
По умолчанию список может открываться после ввода первого символа.
Параметр minChars определяет минимальную длину строки
поиска.
new Awesomplete(input, {
minChars: 3
});
Теперь подсказки появятся только после ввода трёх символов.
Это полезно при работе с большими объёмами данных.
Параметр maxItems задаёт максимальное число отображаемых
вариантов.
new Awesomplete(input, {
maxItems: 5
});
Даже если найдено двадцать совпадений, пользователю будут показаны только первые пять.
Свойство autoFirst включает автоматическую фокусировку
первого элемента списка.
new Awesomplete(input, {
autoFirst: true
});
После открытия выпадающего списка первый вариант будет сразу активен для выбора клавишей Enter.
Список может изменяться динамически.
autocomplete.list = [
"React",
"Vue",
"Angular",
"Svelte"
];
После присвоения нового массива компонент автоматически начинает использовать обновлённые данные.
Во многих приложениях требуется отображать один текст, а сохранять другой.
Например:
[
{
label: "JavaScript",
value: 1
},
{
label: "Python",
value: 2
}
]
Для таких случаев используются функции обработки данных.
new Awesomplete(input, {
list: data
});
Далее настраиваются собственные методы фильтрации и отображения.
Awesomplete предоставляет встроенную функцию фильтрации.
По умолчанию выполняется поиск совпадений по введённому тексту.
Пример пользовательского фильтра:
new Awesomplete(input, {
filter: function(text, inputValue) {
return text.startsWith(inputValue);
}
});
Теперь будут отображаться только элементы, начинающиеся с введённой последовательности символов.
Для большинства интерфейсов важна нечувствительность к регистру.
filter: function(text, inputValue) {
return text
.toLowerCase()
.includes(inputValue.toLowerCase());
}
Такой подход обеспечивает более удобный пользовательский опыт.
При использовании объектов возможно выполнять поиск сразу по нескольким свойствам.
filter(item, inputValue) {
return (
item.name.includes(inputValue) ||
item.code.includes(inputValue)
);
}
Подобный механизм часто применяется в каталогах товаров и справочниках.
После фильтрации найденные элементы могут сортироваться.
sort: function(a, b) {
return a.localeCompare(b);
}
Сортировка выполняется перед отображением списка.
Например, можно поднимать наиболее точные совпадения вверх.
sort: function(a, b) {
return a.length - b.length;
}
Короткие совпадения окажутся выше длинных.
Метод item отвечает за формирование HTML-разметки
каждого результата.
item: function(text) {
const li = document.createElement("li");
li.textContent = text;
return li;
}
Функция должна возвращать DOM-элемент.
Часто совпадающая часть строки подсвечивается.
item: function(text, inputValue) {
const li = document.createElement("li");
li.innerHTML = text.replace(
new RegExp(inputValue, "gi"),
"<mark>$&</mark>"
);
return li;
}
Подсветка делает поиск более наглядным.
После выбора элемента можно контролировать процесс вставки значения.
replace: function(text) {
this.input.value = text.toUpperCase();
}
В приведённом примере выбранное значение преобразуется в верхний регистр.
Одним из наиболее востребованных сценариев является работа с сервером.
input.addEventListener("input", async function() {
const response = await fetch(
"/api/search?q=" + input.value
);
const data = await response.json();
awesomplete.list = data;
});
После получения ответа список автоматически обновляется.
Частые обращения к серверу могут создавать лишнюю нагрузку.
Поэтому обычно применяется debounce.
function debounce(fn, delay) {
let timer;
return function(...args) {
clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(this, args);
}, delay);
};
}
Использование:
input.addEventListener(
"input",
debounce(loadData, 300)
);
Теперь запросы будут отправляться не чаще одного раза за 300 миллисекунд.
Awesomplete генерирует набор специальных событий.
Наиболее важные:
awesomplete-open;awesomplete-close;awesomplete-highlight;awesomplete-select;awesomplete-selectcomplete.input.addEventListener(
"awesomplete-open",
function() {
console.log("Список открыт");
}
);
input.addEventListener(
"awesomplete-close",
function() {
console.log("Список закрыт");
}
);
input.addEventListener(
"awesomplete-select",
function(event) {
console.log(
event.text.value
);
}
);
Событие возникает непосредственно перед вставкой значения.
input.addEventListener(
"awesomplete-selectcomplete",
function(event) {
console.log(
event.text.value
);
}
);
На этом этапе значение уже вставлено в поле ввода.
Иногда требуется управлять компонентом вручную.
awesomplete.open();
Список будет открыт независимо от пользовательского ввода.
awesomplete.close();
Выпадающее меню немедленно скроется.
При работе с тысячами записей возникают дополнительные требования к оптимизации.
Основные методы повышения производительности:
Для массивов размером в несколько десятков тысяч элементов предпочтительно выполнять поиск на серверной стороне.
Пример загрузки данных из внешнего сервиса:
async function search(query) {
const response = await fetch(
`/api/products?q=${query}`
);
return response.json();
}
Подключение:
input.addEventListener(
"input",
async function() {
const results =
await search(input.value);
awesomplete.list = results;
}
);
Такой подход позволяет работать практически с неограниченными объёмами данных.
Awesomplete создаёт собственную HTML-структуру.
Пример изменения оформления списка:
.awesomplete ul {
border-radius: 8px;
box-shadow: 0 5px 20px rgba(0,0,0,.15);
}
Настройка активного элемента:
.awesomplete li[aria-selected="true"] {
background: #2d6cdf;
color: white;
}
Оформление полностью контролируется обычными CSS-правилами.
Библиотека поддерживает:
Это позволяет использовать компонент в интерфейсах с повышенными требованиями к доступности.
Awesomplete часто используется для реализации:
Благодаря небольшому размеру, гибкой настройке фильтрации, поддержке пользовательского отображения, асинхронной загрузке данных и развитой системе событий Awesomplete остаётся удобным инструментом для создания производительных механизмов автодополнения в современных JavaScript-приложениях.