Работа автодополнения в контексте HTML-форм требует не только отображения подсказок, но и корректного управления значениями инпутов, синхронизации состояния, а также подготовки данных к отправке. В связке с формами Awesomplete выступает как слой UI-логики, не вмешиваясь в механизм сабмита, но изменяя поведение полей ввода.
Основная идея использования заключается в привязке экземпляра
Awesomplete к стандартному <input> внутри
<form>, после чего управление значениями остаётся за
браузерной формой, а библиотека отвечает за удобство ввода.
Структура формы остаётся стандартной:
<form id="searchForm">
<input id="cityInput" name="city" />
<button type="submit">Отправить</button>
</form>
Инициализация Awesomplete выполняется напрямую на поле:
const input = document.querySelector("#cityInput");
const awesomplete = new Awesomplete(input, {
list: ["Almaty", "Astana", "Shymkent", "Karaganda"]
});
Поведение формы при этом не меняется: значение поля отправляется как
обычно через name="city".
В типичной реализации отображаемое значение совпадает с отправляемым. Однако часто требуется разделение UI-значения и фактического идентификатора.
const cities = [
{ label: "Almaty", value: "ALA" },
{ label: "Astana", value: "NQZ" },
{ label: "Karaganda", value: "KGF" }
];
const awesomplete = new Awesomplete(input, {
list: cities.map(c => c.label)
});
Для синхронизации с кодом используется обработчик выбора:
input.addEventListener("awesomplete-selectcomplete", function (e) {
const selectedLabel = e.text.value;
const city = cities.find(c => c.label === selectedLabel);
input.dataset.value = city ? city.value : "";
});
В этом случае форма отправляет визуальное значение, а скрытый атрибут хранит код.
Часто требуется отправка не текста, а идентификатора. Тогда структура формы расширяется:
<form id="cityForm">
<input id="cityInput" autocomplete="off" />
<input type="hidden" name="city_id" id="cityId" />
<button type="submit">Send</button>
</form>
Связка реализуется через событие выбора:
const input = document.querySelector("#cityInput");
const hidden = document.querySelector("#cityId");
const cities = [
{ label: "Almaty", value: "ALA" },
{ label: "Astana", value: "NQZ" }
];
new Awesomplete(input, {
list: cities.map(c => c.label)
});
input.addEventListener("awesomplete-selectcomplete", function (e) {
const selected = cities.find(c => c.label === e.text.value);
hidden.value = selected ? selected.value : "";
});
Такой подход отделяет UI-слой от слоя данных формы.
Проблема возникает, когда пользователь вводит значение вручную и не выбирает элемент из подсказки. В этом случае требуется валидация перед отправкой.
const form = document.querySelector("#cityForm");
form.addEventListener("submit", function (e) {
const value = input.value;
const exists = cities.some(c => c.label === value);
if (!exists) {
e.preventDefault();
hidden.value = "";
}
});
Подобная проверка предотвращает отправку невалидных значений.
При строгих формах допускается блокировка ввода значений вне списка. Awesomplete не ограничивает ввод по умолчанию, поэтому логика реализуется отдельно.
input.addEventListener("blur", function () {
const match = cities.some(c => c.label === input.value);
if (!match) {
input.value = "";
hidden.value = "";
}
});
Такой механизм обеспечивает целостность данных формы.
Формы часто содержат несколько полей с автодополнением, например город и страна.
<form id="geoForm">
<input id="country" name="country" />
<input id="city" name="city" />
</form>
new Awesomplete(document.querySelector("#country"), {
list: ["Kazakhstan", "Russia", "China"]
});
new Awesomplete(document.querySelector("#city"), {
list: ["Almaty", "Moscow", "Beijing"]
});
Каждое поле работает независимо, но при необходимости возможна зависимая логика.
Сценарий «страна → города» требует динамического обновления списка.
const data = {
Kazakhstan: ["Almaty", "Astana", "Karaganda"],
Russia: ["Moscow", "Kazan", "Sochi"]
};
const countryInput = document.querySelector("#country");
const cityInput = document.querySelector("#city");
const cityAwesomplete = new Awesomplete(cityInput, {
list: []
});
countryInput.addEventListener("awesomplete-selectcomplete", function (e) {
const cities = data[e.text.value] || [];
cityAwesomplete.list = cities;
});
Такой подход позволяет изменять контекст автодополнения в зависимости от состояния формы.
Если значение родительского поля меняется, дочерние данные должны сбрасываться:
countryInput.addEventListener("input", function () {
cityInput.value = "";
});
Это предотвращает ситуацию, когда выбранный город не соответствует выбранной стране.
Awesomplete предоставляет событие
awesomplete-selectcomplete, которое фиксирует финальный
выбор пользователя. Это событие используется как точка синхронизации
состояния формы.
input.addEventListener("awesomplete-selectcomplete", function (e) {
console.log("Выбран элемент:", e.text.value);
});
При отправке формы актуальное значение уже считается валидным, если синхронизация выполнена корректно.
В некоторых сценариях значение формы задаётся программно, например при редактировании записи.
input.value = "Almaty";
hidden.value = "ALA";
Для корректной работы автодополнения важно, чтобы значение соответствовало одному из элементов списка, иначе подсказки могут работать некорректно при последующем вводе.
При сбросе формы требуется очистить не только поля, но и связанные состояния.
form.addEventListener("reset", function () {
hidden.value = "";
});
Awesomplete не хранит внутреннего состояния формы, поэтому достаточно очистки связанных значений.
В SPA-сценариях форма часто перехватывается:
form.addEventListener("submit", function (e) {
e.preventDefault();
const payload = {
city: hidden.value
};
fetch("/api", {
method: "POST",
body: JSON.stringify(payload)
});
});
В этом случае Awesomplete влияет только на ввод, не участвуя в отправке данных напрямую.
Awesomplete в контексте форм функционирует как слой улучшения UX над
стандартными <input>:
list.Такая архитектура обеспечивает предсказуемое поведение формы при сохранении гибкости автодополнения.