Массивы объектов

Библиотека Awesomplete поддерживает работу не только с массивами строк, но и с массивами объектов, что позволяет строить автодополнение с разделением отображаемого текста и фактического значения, а также хранить произвольные метаданные для каждого элемента списка.

Такой подход используется в сценариях, где простой строковой модели недостаточно: идентификаторы, коды, сложные подписи, результаты поиска из API, элементы справочников и каталоги.


Структура массива объектов

Базовая идея заключается в том, что каждый элемент списка — это объект, содержащий минимум два поля:

  • label — текст, который отображается пользователю в выпадающем списке
  • value — значение, которое подставляется в input при выборе элемента

Пример структуры:

const list = [
  { label: "Москва", value: "MOW" },
  { label: "Санкт-Петербург", value: "LED" },
  { label: "Новосибирск", value: "OVB" }
];

Awesomplete автоматически использует label для отображения, а value для вставки в поле ввода.


Инициализация Awesomplete с объектами

При инициализации можно передать массив объектов напрямую:

const input = document.querySelector("#city");

const awesomplete = new Awesomplete(input, {
  list: [
    { label: "Москва", value: "MOW" },
    { label: "Казань", value: "KZN" },
    { label: "Екатеринбург", value: "SVX" }
  ]
});

После выбора элемента в поле ввода попадёт значение value, а не label.


Разделение отображения и значения

Ключевая особенность объектного подхода — разделение UI-слоя и данных.

Поле Назначение
label то, что видит пользователь
value то, что используется в логике приложения

Пример поведения:

// пользователь видит: "Москва"
// в input попадает: "MOW"

Это особенно полезно для:

  • кодов стран и городов
  • ID товаров
  • внутренних ключей базы данных
  • API-параметров

Использование дополнительных полей

Объекты могут содержать любые дополнительные данные, не ограничиваясь label и value:

const list = [
  {
    label: "Москва",
    value: "MOW",
    region: "Центральный",
    population: 12500000
  },
  {
    label: "Новосибирск",
    value: "OVB",
    region: "Сибирский",
    population: 1600000
  }
];

Awesomplete игнорирует дополнительные поля, но они становятся доступными при обработке события выбора.


Доступ к выбранному объекту

При выборе элемента можно перехватить событие и получить весь объект через сопоставление значения:

input.addEventListener("awesomplete-selectcomplete", function (e) {
  const selectedValue = e.text.value;

  const selectedItem = awesomplete._list.find(
    item => item.value === selectedValue
  );

  console.log(selectedItem);
});

Такой подход позволяет работать с полными данными записи, а не только с отображаемым значением.


Кастомизация отображения элементов списка

По умолчанию Awesomplete отображает label, но можно переопределить форматирование через item:

new Awesomplete(input, {
  list: [
    { label: "Москва", value: "MOW", region: "Центр" },
    { label: "Казань", value: "KZN", region: "Поволжье" }
  ],
  item: function (text, input) {
    const li = document.createElement("li");

    li.innerHTML = `
      <span class="city-name">${text.label}</span>
      <small class="city-region">${text.region}</small>
    `;

    return li;
  }
});

Таким образом список может превращаться в полноценный UI-компонент с дополнительными деталями.


Кастомизация логики фильтрации

Фильтрация по умолчанию работает по label, но её можно изменить через filter:

new Awesomplete(input, {
  list: [
    { label: "Москва", value: "MOW", code: "01" },
    { label: "Минск", value: "MSQ", code: "02" }
  ],
  filter: function (text, input) {
    return (
      text.label.toLowerCase().includes(input.toLowerCase()) ||
      text.code.includes(input)
    );
  }
});

Теперь поиск работает как по названию, так и по коду.


Сортировка элементов массива объектов

Можно управлять порядком отображения через sort:

new Awesomplete(input, {
  list: cities,
  sort: function (a, b) {
    return a.label.localeCompare(b.label);
  }
});

Сортировка выполняется до фильтрации и влияет на итоговый порядок предложений.


Динамическая генерация массива объектов

Часто данные приходят из API, и список формируется динамически:

fetch("/api/cities")
  .then(res => res.json())
  .then(data => {
    const formatted = data.map(item => ({
      label: item.name,
      value: item.id,
      country: item.country
    }));

    new Awesomplete(input, {
      list: formatted
    });
  });

Такой подход позволяет интегрировать Awesomplete с любыми серверными источниками.


Обновление списка объектов

Если данные меняются после инициализации, список можно обновить:

awesomplete.list = [
  { label: "Берлин", value: "BER" },
  { label: "Париж", value: "PAR" }
];

После обновления новый список начинает использоваться без пересоздания экземпляра.


Работа с replace и объектами

Функция replace управляет тем, что именно вставляется в input:

new Awesomplete(input, {
  list: cities,
  replace: function (suggestion) {
    this.input.value = suggestion.value;
  }
});

Здесь можно полностью контролировать поведение выбора, например подставлять ID, код или комбинированное значение.


Комбинированные отображаемые значения

В некоторых случаях удобно объединять поля в label:

const list = [
  {
    label: "Москва (Россия)",
    value: "MOW",
    country: "RU"
  }
];

Это упрощает восприятие пользователем при большом количестве одноимённых элементов.


Использование с автодополнением из справочников

Объектный формат особенно эффективен при работе со справочниками:

const products = [
  { label: "iPhone 15 Pro", value: 101 },
  { label: "Samsung S24", value: 102 },
  { label: "Xiaomi 14", value: 103 }
];

После выбора можно использовать value как ключ для загрузки данных товара.


Типичные ошибки при работе с массивами объектов

Неправильное использование часто связано с несоответствием структуры:

  • отсутствие label приводит к пустому отображению
  • отсутствие value усложняет обработку выбора
  • попытка использовать нестандартные поля без кастомизации item

Корректная структура всегда должна учитывать поведение Awesomplete, основанное на label/value.


Совмещение строк и объектов в одном списке

Допускается смешанный формат:

list: [
  "Простой элемент",
  { label: "Москва", value: "MOW" }
]

В этом случае строковые элементы автоматически трактуются как label и value одновременно.