При работе с множественным выбором в Awesomplete ключевой задачей становится контроль корректности каждого введённого значения. В отличие от одиночного автодополнения, где валидируется одно поле, здесь требуется учитывать набор независимых токенов, каждый из которых проходит собственный цикл проверки.
Множественный ввод обычно реализуется через разделение строки на элементы (теги, токены, значения списка). В таком сценарии валидатор работает не с полем целиком, а с результатом разбиения.
Первый этап валидации — нормализация ввода. Строка преобразуется в массив значений:
function splitValues(input) {
return input
.split(',')
.map(v => v.trim())
.filter(Boolean);
}
Каждый элемент массива становится самостоятельной единицей проверки. Такой подход позволяет отделить синтаксическую обработку (разделение) от семантической (валидации значения).
При интеграции с Awesomplete этот этап часто выполняется либо в
обработчиках событий input, либо в кастомной функции
replace.
После разбиения необходимо убедиться, что каждый элемент входит в
список допустимых значений. В базовом варианте используется список
allowedValues:
function isValidValue(value, allowedValues) {
return allowedValues.includes(value);
}
Для более сложных сценариев используется нормализация регистра:
function isValidValue(value, allowedValues) {
const normalized = value.toLowerCase();
return allowedValues.some(v => v.toLowerCase() === normalized);
}
В контексте Awesomplete такая проверка часто применяется в функции
filter, которая определяет, какие элементы отображаются в
списке подсказок.
Одной из частых проблем множественного ввода является повторное добавление одинаковых значений. Для предотвращения этого используется проверка на уникальность:
function removeDuplicates(values) {
return [...new Set(values)];
}
Более гибкий вариант учитывает регистр и пробелы:
function normalize(value) {
return value.trim().toLowerCase();
}
function removeDuplicates(values) {
const seen = new Set();
return values.filter(v => {
const key = normalize(v);
if (seen.has(key)) return false;
seen.add(key);
return true;
});
}
При использовании Awesomplete дубликаты часто фильтруются на этапе
обработки события selectcomplete, когда значение уже
добавлено в поле.
Для строгих форматов (email, коды, идентификаторы) применяется проверка через регулярные выражения:
const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
function validateEmail(value) {
return emailPattern.test(value);
}
Если ввод представляет собой список email-адресов, проверка выполняется для каждого токена:
function validateAll(values) {
return values.every(validateEmail);
}
В связке с Awesomplete это позволяет блокировать сохранение некорректных значений ещё до добавления в список.
Awesomplete предоставляет несколько точек расширения, которые используются для валидации:
filter — управление отображением подсказокitem — кастомизация элемента спискаreplace — управление вставкой выбранного значенияselectcomplete — обработка завершённого выбораНаиболее важная логика множественной валидации обычно сосредоточена в
replace:
awesomplete.replace = function (suggestion) {
const values = splitValues(input.value);
values.pop();
values.push(suggestion.label);
const cleaned = removeDuplicates(values);
input.value = cleaned.join(", ");
};
Таким образом, каждое новое значение проходит через цепочку нормализации и проверки.
Иногда требуется полностью запретить добавление значений, не
прошедших проверку. В этом случае используется контроль в
select или selectcomplete:
input.addEventListener("awesomplete-selectcomplete", function (e) {
const value = e.text.value;
if (!isValidValue(value, allowedValues)) {
e.preventDefault();
}
});
В рамках Awesomplete такой подход позволяет перехватывать момент вставки и предотвращать загрязнение данных.
Для динамических списков допустимых значений используется серверная проверка:
async function validateOnServer(value) {
const res = await fetch(`/validate?q=${encodeURIComponent(value)}`);
const data = await res.json();
return data.valid;
}
При множественном вводе проверка выполняется последовательно или параллельно:
async function validateValues(values) {
const results = await Promise.all(values.map(validateOnServer));
return results.every(Boolean);
}
В таких сценариях Awesomplete выступает только как слой интерфейса, а вся бизнес-логика переносится на серверную часть.
Валидация должна сопровождаться визуальной обратной связью. Распространённый подход — добавление CSS-классов:
function markInvalid(input) {
input.classList.add("invalid");
}
function markValid(input) {
input.classList.remove("invalid");
}
При проверке списка:
if (!validateAll(values)) {
markInvalid(input);
} else {
markValid(input);
}
В связке с Awesomplete это позволяет сохранять единый UX между вводом и выбором.
Множественный ввод часто ограничивается максимальным количеством значений:
const MAX_ITEMS = 5;
function isWithinLimit(values) {
return values.length <= MAX_ITEMS;
}
При превышении лимита добавление нового значения блокируется:
awesomplete.replace = function (suggestion) {
const values = splitValues(input.value);
if (values.length >= MAX_ITEMS) return;
values.push(suggestion.label);
input.value = values.join(", ");
};
В Awesomplete такие ограничения особенно важны при работе с тегами и фильтрами.
Полноценная система проверки включает несколько уровней:
Эта цепочка обеспечивает устойчивое поведение интерфейса даже при сложных сценариях множественного выбора в Awesomplete.