Переход на Awesomplete в существующих проектах почти всегда связан с
заменой более тяжёлых или фреймворк-зависимых решений автодополнения.
Основная особенность миграции заключается в том, что Awesomplete
минималистична: отсутствует жёсткая привязка к DOM-структурам, нет
обязательных зависимостей и почти вся логика строится вокруг одного
конструктора и набора атрибутов элемента <input>.
Ключевая задача миграции — не переписать поведение один в один, а адаптировать существующие сценарии к более низкоуровневой модели управления списком подсказок.
jQuery UI Autocomplete предполагает декларативное поведение через
вызов метода .autocomplete() и богатую систему событий. В
Awesomplete аналогичная логика распределяется между инициализацией и
событиями экземпляра.
$("#city").autocomplete({
source: ["Berlin", "Bern", "Barcelona"],
minLength: 2,
select: function(event, ui) {
console.log(ui.item.value);
}
});
const input = document.querySelector("#city");
const awesomplete = new Awesomplete(input, {
minChars: 2,
list: ["Berlin", "Bern", "Barcelona"]
});
input.addEventListener("awesomplete-selectcomplete", function(e) {
console.log(e.text.value);
});
source заменяется на listminLength становится minCharsselect превращается в DOM-событие
awesomplete-selectcompleteAwesomplete, а
не через jQuery-обёрткуTypeahead.js использует сложную модель datasets и Bloodhound для поиска. Awesomplete заменяет это простой функцией или массивом.
var engine = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.whitespace,
queryTokenizer: Bloodhound.tokenizers.whitespace,
local: ["Amsterdam", "Athens", "Auckland"]
});
$("#city").typeahead(null, {
source: engine
});
const input = document.querySelector("#city");
new Awesomplete(input, {
list: ["Amsterdam", "Athens", "Auckland"]
});
Select2 совмещает автодополнение и кастомные
<select> компоненты. Awesomplete работает
исключительно с <input>, поэтому требуется изменение
модели данных.
$("#city").select2({
data: [
{ id: 1, text: "Berlin" },
{ id: 2, text: "Bern" }
]
});
const input = document.querySelector("#city");
new Awesomplete(input, {
list: ["Berlin", "Bern"]
});
{id, text} заменяется на строкуnew Awesomplete(input, {
list: [
"1|Berlin",
"2|Bern"
]
});
И последующая обработка:
input.addEventListener("awesomplete-selectcomplete", function(e) {
const [id, text] = e.text.value.split("|");
});
Этот плагин часто используется в старых проектах и имеет AJAX-ориентированную модель.
$("#city").autocomplete({
serviceUrl: "/api/cities",
onSelect: function(suggestion) {
console.log(suggestion.value);
}
});
const input = document.querySelector("#city");
const awesomplete = new Awesomplete(input, {
minChars: 1
});
input.addEventListener("input", async function() {
const res = await fetch(`/api/cities?q=${this.value}`);
const data = await res.json();
awesomplete.list = data.map(item => item.name);
awesomplete.evaluate();
});
list +
evaluate()Choices.js работает с <select multiple> и тегами.
Awesomplete не поддерживает мультиселект напрямую, поэтому требуется
адаптация логики.
new Choices("#city", {
choices: [
{ value: "Berlin", label: "Berlin" },
{ value: "Bern", label: "Bern" }
],
removeItemButton: true
});
const input = document.querySelector("#city");
const selected = [];
const awesomplete = new Awesomplete(input, {
list: ["Berlin", "Bern"]
});
input.addEventListener("awesomplete-selectcomplete", function(e) {
selected.push(e.text.value);
input.value = "";
});
Во многих библиотеках фильтрация происходит на уровне источника данных. Awesomplete использует встроенный фильтр, но допускает переопределение.
matcher: function(item, query) {
return item.startsWith(query);
}
new Awesomplete(input, {
list: ["Berlin", "Bern", "Barcelona"],
filter: function(text, input) {
return text.toLowerCase().indexOf(input.toLowerCase()) === 0;
}
});
Миграция часто требует замены встроенных AJAX-механизмов на ручное управление списком.
inputawesomplete.listevaluate()const input = document.querySelector("#city");
const awesomplete = new Awesomplete(input, {
minChars: 2,
list: []
});
let timeout;
input.addEventListener("input", function() {
clearTimeout(timeout);
timeout = setTimeout(async () => {
const res = await fetch(`/api/search?q=${this.value}`);
const data = await res.json();
awesomplete.list = data;
awesomplete.evaluate();
}, 200);
});
В старых библиотеках часто используются собственные события. В Awesomplete необходимо использовать стандартные DOM event listeners.
Awesomplete не возвращает jQuery-объект, поэтому конструкции вида:
$("#city").data().autocomplete
становятся неприменимыми.
evaluate()При динамическом обновлении списка забывают вызвать перерасчёт, из-за чего UI не обновляется.
В процессе миграции часто происходит переход от сложных структур:
{ id: 10, name: "Berlin", country: "DE" }
к упрощённым строкам или плоским форматам:
"Berlin"
При необходимости сохранения метаданных используется сериализация:
"10::Berlin::DE"
с последующим разбором при выборе.
Некоторые библиотеки позволяют переопределять шаблоны. Awesomplete
делает ставку на минимальный UI, поэтому кастомизация достигается через
CSS и частично через item форматирование.
new Awesomplete(input, {
list: ["Berlin", "Bern"]
});
Стилизация:
.awesomplete ul {
border: 1px solid #ccc;
}
.awesomplete li[aria-selected="true"] {
background: #eee;
}
Переход на Awesomplete почти всегда означает упрощение архитектуры автодополнения. Вместо сложных систем с несколькими уровнями абстракции остаётся один объект, один input и явное управление данными.