Миграция с других библиотек

Основная задача миграции на Slim Select заключается в переводе существующей логики работы с выпадающими списками из других решений — таких как Select2, Choices.js или Chosen — в более легковесную, модульную и предсказуемую модель управления состоянием без зависимости от jQuery и сложных DOM-манипуляций.

Различные библиотеки решают одну задачу разными подходами:

  • Select2 / Chosen опираются на jQuery и глубоко модифицируют DOM
  • Choices.js использует более современный подход, но сохраняет собственный слой управления состоянием
  • Slim Select строится вокруг минимального API и прямой работы с нативным <select>

Ключевое отличие миграции заключается в переходе:

  • от императивного управления DOM
  • к декларативной инициализации через конфигурацию

Slim Select не требует постоянного синхронизирования состояния вручную — состояние всегда выводится из <select>.

Модель данных и её преобразование

В старых решениях данные часто формируются через кастомные структуры:

  • Select2: массив объектов { id, text }
  • Choices.js: { value, label, selected, disabled }
  • Chosen: зависит от DOM <option>

Slim Select использует упрощённую модель:

  • либо стандартный <option>
  • либо массив { text, value } при программной инициализации

Пример миграции структуры данных

Select2:

$('#select').select2({
  data: [
    { id: 1, text: 'Apple' },
    { id: 2, text: 'Orange' }
  ]
});

Slim Select:

new SlimSelect({
  select: '#select',
  data: [
    { text: 'Apple', value: '1' },
    { text: 'Orange', value: '2' }
  ]
});

Основное преобразование:

  • idvalue
  • text остаётся text

Инициализация компонента

jQuery-based подход (Select2 / Chosen)

$('#select').select2();

или

$('#select').chosen();

Slim Select

new SlimSelect({
  select: '#select'
});

Миграционные изменения

  • убирается $()
  • убираются глобальные плагины jQuery
  • используется new-инициализация
  • селектор передаётся строкой или DOM-элементом

Работа с асинхронными данными

В Select2 и Choices.js часто используется собственный AJAX-слой.

Select2 AJAX пример

$('#select').select2({
  ajax: {
    url: '/api/search',
    processResults: function (data) {
      return {
        results: data.items
      };
    }
  }
});

Slim Select эквивалент

Slim Select не включает встроенный AJAX-слой в классическом виде, поэтому миграция выполняется через внешний fetch:

const slim = new SlimSelect({
  select: '#select',
  data: []
});

fetch('/api/search')
  .then(res => res.json())
  .then(data => {
    slim.setData(
      data.items.map(item => ({
        text: item.name,
        value: item.id
      }))
    );
  });

Ключевая трансформация:

  • AJAX логика выносится из конфигурации
  • обновление данных выполняется через setData

События и их переработка

Select2 события

$('#select').on('change', function (e) {
  console.log(e.target.value);
});

Slim Select события

new SlimSelect({
  select: '#select',
  events: {
    afterChange: (newVal) => {
      console.log(newVal);
    }
  }
});

Сопоставление событий

Select2 / Chosen Slim Select
change afterChange
select2:open open
select2:close close

Основное изменение — переход от jQuery event bus к конфигурационным callback-функциям.

Управление значениями

Получение значения

Select2:

$('#select').val();

Slim Select:

slim.getSelected();

Установка значения

Select2:

$('#select').val('1').trigger('change');

Slim Select:

slim.setSelected('1');

Миграционная разница

  • исчезает необходимость trigger-based обновлений
  • состояние управляется напрямую через API

Работа с множественным выбором

В Select2 и Choices.js множественный выбор часто требует отдельной конфигурации.

Select2

$('#select').select2({
  multiple: true
});

Slim Select

new SlimSelect({
  select: '#select'
});

HTML:

<select multiple>
  <option value="1">A</option>
  <option value="2">B</option>
</select>

Особенность миграции:

  • атрибут multiple остаётся единственным источником правды
  • JavaScript не дублирует эту настройку

Переход от кастомного DOM к Slim Select

В старых библиотеках часто используются:

  • кастомные dropdown контейнеры
  • ручное управление классами
  • перерисовка DOM

Slim Select полностью инкапсулирует DOM-логику.

Пример устаревшего подхода (Chosen)

$('#select').chosen();
$('#select').trigger('chosen:updated');

Slim Select

const slim = new SlimSelect({
  select: '#select'
});

slim.setData([
  { text: 'A', value: 'a' }
]);

Обновление DOM происходит автоматически.

Стилизация и миграция CSS

Select2

  • сложная CSS-структура
  • необходимость переопределения классов .select2-container

Choices.js

  • BEM-подобные классы
  • множество уровней вложенности

Slim Select

  • минимальное количество классов
  • простая структура:
.ss-main {}
.ss-single {}
.ss-multi {}
.ss-option {}

Миграционные изменения в CSS

  • удаляются глубокие селекторы
  • упрощается кастомизация темы
  • уменьшается вероятность конфликтов

Частые проблемы при миграции

Потеря синхронизации состояния

В старых библиотеках состояние часто дублируется:

  • DOM
  • JS-объект
  • скрытые input-поля

Slim Select использует единую точку состояния — <select>.

Несовместимость форматов данных

Частая ошибка:

  • использование id вместо value
  • отсутствие преобразования типов (string vs number)

Решение — явная нормализация:

data.map(item => ({
  text: item.title,
  value: String(item.id)
}));

Ошибки из-за trigger-based логики

Код вида:

$('#select').val('1').trigger('change');

не имеет прямого аналога и заменяется:

slim.setSelected('1');

Перенос сложной логики поиска

В Select2 используется встроенный search engine с кастомными matcher-функциями:

matcher: function (params, data) {
  return data.text.includes(params.term);
}

В Slim Select подобная логика переносится в preprocessing данных:

const filtered = data.filter(item =>
  item.text.toLowerCase().includes(query.toLowerCase())
);

slim.setData(filtered);

Таким образом:

  • фильтрация становится внешней задачей
  • библиотека отвечает только за UI

Итоговые принципы миграции

Структурные изменения сводятся к следующим переходам:

  • jQuery → нативный JavaScript
  • DOM manipulation → state-driven API
  • AJAX внутри конфигурации → внешний fetch слой
  • events API → callback functions
  • complex CSS → минималистичная стилизация
  • trigger-based updates → прямые методы управления состоянием