В типичных сценариях автодополнения пользователь вводит часть строки,
после чего система подставляет выбранный элемент целиком. Однако в
реальных интерфейсах часто требуется более гибкая логика: вставка не
полного значения, а только его части, либо замена конкретного фрагмента
внутри составного текста. Библиотека Awesomplete позволяет управлять
этим процессом через переопределение поведения вставки и работу с
функцией replace.
По умолчанию Awesomplete использует простую стратегию: при выборе элемента выпадающего списка текущее содержимое input полностью заменяется значением выбранного элемента.
Пример стандартного поведения:
const input = document.querySelector("#city");
new Awesomplete(input, {
list: ["Almaty", "Astana", "Shymkent"]
});
При выборе Astana текущее значение поля становится
строго Astana, независимо от уже введённого текста.
Такой подход подходит для одиночных значений, но становится ограничением при работе с составными строками.
Ключевая точка расширения логики вставки — метод
replace. Он определяет, каким образом выбранный элемент
списка преобразуется в значение input.
Сигнатура поведения задаётся через опцию:
new Awesomplete(input, {
list: ["JavaScript", "Java", "Python"],
replace: function (suggestion) {
this.input.value = suggestion;
}
});
Здесь suggestion — выбранный элемент списка, а
this.input.value — поле ввода.
Однако основная сила replace проявляется тогда, когда
необходимо работать не с полным значением, а с его частью.
Одна из распространённых задач — замена только последнего введённого фрагмента, а не всей строки.
Пример: ввод нескольких языков через запятую.
const input = document.querySelector("#langs");
new Awesomplete(input, {
list: ["JavaScript", "Java", "Python", "PHP"],
replace: function (suggestion) {
const value = this.input.value;
const parts = value.split(",");
parts.pop();
parts.push(suggestion);
this.input.value = parts.join(", ");
}
});
Здесь реализуется ключевой принцип частичной вставки:
Такой подход используется в тегах, списках навыков, email-адресах и фильтрах.
Частичная замена может быть привязана не только к последнему элементу, но и к позиции курсора.
replace: function (suggestion) {
const input = this.input;
const start = input.selectionStart;
const end = input.selectionEnd;
const before = input.value.substring(0, start);
const after = input.value.substring(end);
input.value = before + suggestion + after;
}
Такой механизм позволяет:
Awesomplete в этом случае выступает не просто автодополнением, а инструментом контекстной вставки.
Часто ввод содержит структурированные данные: ключевые слова, хэштеги, параметры запроса.
Пример обработки токена #:
new Awesomplete(input, {
list: ["javascript", "webdev", "css", "html"],
replace: function (suggestion) {
const value = this.input.value;
const hashIndex = value.lastIndexOf("#");
this.input.value =
value.substring(0, hashIndex + 1) + suggestion + " ";
}
});
Поведение:
#Это позволяет строить системы хэштегов и командного ввода.
Awesomplete поддерживает объекты в списке, где отображаемый текст и фактическое значение различаются.
new Awesomplete(input, {
list: [
{ label: "United States", value: "US" },
{ label: "United Kingdom", value: "UK" }
],
replace: function (item) {
this.input.value = item.value;
}
});
В этом случае:
label отображается пользователюvalue используется при вставкеЧастичная вставка может использовать оба поля одновременно:
replace: function (item) {
const parts = this.input.value.split(":");
parts[1] = item.value;
this.input.value = parts.join(":");
}
При работе с textarea логика частичной подстановки усложняется из-за наличия переносов строк.
replace: function (suggestion) {
const lines = this.input.value.split("\n");
const lastLineIndex = lines.length - 1;
lines[lastLineIndex] = suggestion;
this.input.value = lines.join("\n");
}
Такой подход полезен для:
При частичной подстановке часто возникает проблема лишних пробелов и запятых.
replace: function (suggestion) {
let value = this.input.value;
value = value.replace(/\s*,\s*$/, "");
this.input.value = value + ", " + suggestion;
}
Здесь выполняется нормализация:
Awesomplete не ограничивает способ определения заменяемого фрагмента. Логика может полностью зависеть от контекста ввода.
Пример выделения слова под курсором:
function getWordBounds(value, position) {
const left = value.slice(0, position).search(/\S+$/);
const right = value.slice(position).search(/\s/);
return {
start: left === -1 ? 0 : left,
end: right === -1 ? value.length : position + right
};
}
Использование в replace:
replace: function (suggestion) {
const input = this.input;
const pos = input.selectionStart;
const bounds = getWordBounds(input.value, pos);
input.value =
input.value.slice(0, bounds.start) +
suggestion +
input.value.slice(bounds.end);
}
Частичная подстановка часто сочетается с другими функциями:
Пример динамического расширения:
new Awesomplete(input, {
list: [],
replace: function (suggestion) {
const parts = this.input.value.split(" ");
parts[parts.length - 1] = suggestion;
this.input.value = parts.join(" ");
},
data: function (item) {
return item.toUpperCase();
}
});
Здесь вставка работает совместно с трансформацией данных.
Если разделитель отличается от стандартных пробелов или запятых, логика адаптируется под конкретный формат.
Пример с |:
replace: function (suggestion) {
const parts = this.input.value.split("|");
parts[parts.length - 1] = suggestion;
this.input.value = parts.join("|");
}
Такая модель часто используется в:
Особый случай — когда пользователь не ввёл активный фрагмент, но вызвал список подсказок.
replace: function (suggestion) {
if (!this.input.value.trim()) {
this.input.value = suggestion;
return;
}
const parts = this.input.value.split(" ");
parts[parts.length - 1] = suggestion;
this.input.value = parts.join(" ");
}
Это позволяет избежать некорректной вставки в пустое поле и сохранить предсказуемое поведение интерфейса.