Формат данных

Библиотека Slim Select поддерживает несколько вариантов структуры данных для формирования списка опций, группировки элементов, динамической загрузки и управления состоянием select-компонента. Правильный формат данных играет ключевую роль при работе с API библиотеки, особенно при генерации списков из JavaScript, AJAX-запросов или серверных данных.


Базовая структура данных

Основой Slim Select является массив объектов. Каждый объект описывает отдельную опцию списка.

Простейший формат:

const data = [
  {
    text: 'JavaScript',
    value: 'js'
  },
  {
    text: 'Python',
    value: 'python'
  },
  {
    text: 'PHP',
    value: 'php'
  }
]

Использование:

new SlimSelect({
  select: '#skills',
  data: data
})

Поля объекта

Поле Назначение
text Отображаемый текст
value Значение option
selected Предварительно выбранный элемент
disabled Блокировка опции
placeholder Признак placeholder
html HTML-разметка вместо обычного текста
data Пользовательские data-атрибуты
mandatory Запрет удаления выбранного элемента

Поле text

Поле text определяет содержимое, отображаемое пользователю.

{
  text: 'React',
  value: 'react'
}

Если поле отсутствует, интерфейс будет отображаться некорректно или элемент окажется пустым.

Особенности text

  • поддерживает обычные строки;
  • может содержать Unicode;
  • может использоваться совместно с html;
  • участвует в поиске.

Пример:

{
  text: 'TypeScript',
  value: 'ts'
}

Поле value

Поле value соответствует значению HTML-атрибута value.

{
  text: 'Vue',
  value: 'vue'
}

После выбора:

<option value="vue">Vue</option>

Особенности

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

Пример числовых значений:

[
  {
    text: 'Level 1',
    value: 1
  },
  {
    text: 'Level 2',
    value: 2
  }
]

Предварительный выбор через selected

Для установки активного значения используется поле selected.

const data = [
  {
    text: 'JavaScript',
    value: 'js',
    selected: true
  },
  {
    text: 'Python',
    value: 'python'
  }
]

Multiple select

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

[
  {
    text: 'HTML',
    value: 'html',
    selected: true
  },
  {
    text: 'CSS',
    value: 'css',
    selected: true
  }
]

Блокировка опций через disabled

Поле disabled делает элемент недоступным.

{
  text: 'Недоступный пункт',
  value: 'disabled-item',
  disabled: true
}

HTML-эквивалент:

<option disabled>

Типичные сценарии

  • временно недоступные категории;
  • ограничения тарифов;
  • элементы без доступа;
  • системные значения.

Placeholder-элементы

Placeholder обозначается свойством placeholder.

{
  text: 'Выберите язык',
  placeholder: true
}

Особенности placeholder

  • не является полноценным значением;
  • отображается до выбора;
  • обычно используется совместно с пустым value.

Пример:

{
  text: 'Выберите страну',
  value: '',
  placeholder: true
}

HTML-контент через html

Поле html позволяет использовать полноценную HTML-разметку.

{
  text: 'JavaScript',
  value: 'js',
  html: '<strong>JavaScript</strong>'
}

Возможности html

  • иконки;
  • цветовые метки;
  • изображения;
  • кастомная верстка;
  • бейджи;
  • стилизованные элементы.

Пример с иконкой:

{
  text: 'Node.js',
  value: 'node',
  html: `
    <div class="item">
      <i class="icon-node"></i>
      <span>Node.js</span>
    </div>
  `
}

Важное ограничение

При использовании html поле text всё равно желательно указывать, поскольку оно участвует в поиске и внутренней логике библиотеки.


Пользовательские data-атрибуты

Slim Select поддерживает передачу произвольных data-атрибутов.

{
  text: 'Frontend',
  value: 'frontend',
  data: {
    level: 'middle',
    category: 'web'
  }
}

Результат:

<option
  data-level="middle"
  data-category="web"
>

Где применяется

  • фильтрация;
  • интеграция с API;
  • хранение метаданных;
  • динамические интерфейсы;
  • аналитика.

Обязательные элементы через mandatory

Свойство mandatory запрещает удаление выбранного элемента.

{
  text: 'Администратор',
  value: 'admin',
  selected: true,
  mandatory: true
}

Поведение mandatory

  • элемент нельзя снять вручную;
  • используется в multiple select;
  • полезно для обязательных тегов.

Группы данных

Slim Select поддерживает структуру optgroup через вложенные массивы.


Формат группы

const data = [
  {
    label: 'Frontend',
    options: [
      {
        text: 'React',
        value: 'react'
      },
      {
        text: 'Vue',
        value: 'vue'
      }
    ]
  },
  {
    label: 'Backend',
    options: [
      {
        text: 'Node.js',
        value: 'node'
      }
    ]
  }
]

Поля группы

Поле Назначение
label Заголовок группы
options Массив элементов
selectAll Возможность выбрать всю группу

Заголовок группы

{
  label: 'Databases',
  options: []
}

Соответствует:

<optgroup label="Databases">

Массив options

Внутри options располагаются стандартные объекты Slim Select.

{
  label: 'Languages',
  options: [
    {
      text: 'Go',
      value: 'go'
    }
  ]
}

selectAll для групп

Некоторые конфигурации используют selectAll.

{
  label: 'Frameworks',
  selectAll: true,
  options: [
    {
      text: 'Angular',
      value: 'angular'
    }
  ]
}

Назначение

  • быстрое выделение группы;
  • удобство при large datasets;
  • массовый выбор категорий.

Смешанные структуры

Slim Select позволяет комбинировать группы и одиночные элементы.

const data = [
  {
    text: 'Без группы',
    value: 'single'
  },
  {
    label: 'Languages',
    options: [
      {
        text: 'Rust',
        value: 'rust'
      }
    ]
  }
]

Формат для multiple select

Для multiple-режима структура не меняется.

new SlimSelect({
  select: '#multiple',
  settings: {
    multiple: true
  },
  data: [
    {
      text: 'HTML',
      value: 'html'
    },
    {
      text: 'CSS',
      value: 'css'
    }
  ]
})

Динамическое обновление данных

Slim Select поддерживает замену данных через API.


setData

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

slim.setData([
  {
    text: 'Admin',
    value: '1'
  },
  {
    text: 'Editor',
    value: '2'
  }
])

Что делает setData

  • полностью очищает старый список;
  • создает новые элементы;
  • обновляет DOM;
  • пересчитывает выбранные значения.

Формат данных из API

Часто данные приходят с сервера в неподходящем формате.

Например:

[
  {
    "id": 1,
    "name": "JavaScript"
  },
  {
    "id": 2,
    "name": "Python"
  }
]

Для Slim Select требуется преобразование.


Преобразование массива

const formatted = response.map(item => ({
  text: item.name,
  value: item.id
}))

Использование:

slim.setData(formatted)

Формат данных для AJAX-поиска

При асинхронной загрузке структура остается идентичной.

fetch('/api/tags')
  .then(res => res.json())
  .then(data => {
    slim.setData(
      data.map(tag => ({
        text: tag.title,
        value: tag.id
      }))
    )
  })

Работа с вложенными объектами

Нередко сервер возвращает сложные структуры.

Пример:

[
  {
    "category": "Frontend",
    "items": [
      {
        "id": 1,
        "title": "React"
      }
    ]
  }
]

Преобразование:

const formatted = data.map(group => ({
  label: group.category,
  options: group.items.map(item => ({
    text: item.title,
    value: item.id
  }))
}))

Генерация данных из HTML

Slim Select способен автоматически читать структуру существующего select.

HTML:

<select id="skills">
  <option value="js">JavaScript</option>
  <option value="python">Python</option>
</select>

Jav * aScript:

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

Что происходит внутри

Библиотека самостоятельно:

  • считывает option;
  • формирует внутренний массив;
  • строит интерфейс;
  • синхронизирует состояния.

Внутренний формат данных

После инициализации Slim Select хранит данные во внутреннем состоянии.

Типичная структура:

[
  {
    id: 'option-1',
    value: 'js',
    text: 'JavaScript',
    selected: false
  }
]

Дополнительные внутренние свойства

Библиотека может автоматически добавлять:

  • внутренние идентификаторы;
  • индексы;
  • служебные флаги;
  • ссылки на DOM-элементы.

Формат данных и поиск

Поле text напрямую влияет на встроенный поиск.

{
  text: 'JavaScript',
  value: 'js'
}

Поиск выполняется именно по text, даже если используется html.


Формат данных и производительность

При больших массивах структура данных становится особенно важной.


Рекомендации

Минимизировать html

Сложная HTML-разметка:

html: `
  <div>
    <img src="...">
    <span>Item</span>
  </div>
`

замедляет:

  • рендеринг;
  • поиск;
  • обновление DOM.

Использовать короткие value

value: '1'

лучше, чем:

value: 'very-long-unique-string-value'

при large datasets.


Избегать лишних свойств

Плохо:

{
  text: 'Vue',
  value: 'vue',
  temp1: '...',
  temp2: '...',
  temp3: '...'
}

Лучше:

{
  text: 'Vue',
  value: 'vue'
}

Проверка корректности структуры

Частые ошибки:


Отсутствует text

{
  value: 'js'
}

Результат — пустой пункт.


Отсутствует value

{
  text: 'JavaScript'
}

Может приводить к некорректному выбору.


options не является массивом

Ошибка:

{
  label: 'Group',
  options: {}
}

Правильно:

{
  label: 'Group',
  options: []
}

Дублирующиеся value

[
  {
    text: 'React',
    value: '1'
  },
  {
    text: 'Vue',
    value: '1'
  }
]

Приводит к конфликтам выбора.


Полный пример сложной структуры

const data = [
  {
    text: 'Выберите технологию',
    value: '',
    placeholder: true
  },
  {
    label: 'Frontend',
    options: [
      {
        text: 'React',
        value: 'react',
        data: {
          type: 'frontend'
        }
      },
      {
        text: 'Vue',
        value: 'vue',
        selected: true
      }
    ]
  },
  {
    label: 'Backend',
    options: [
      {
        text: 'Node.js',
        value: 'node',
        disabled: true
      },
      {
        text: 'Laravel',
        value: 'laravel'
      }
    ]
  }
]

Использование:

new SlimSelect({
  select: '#stack',
  data: data
})

Совместимость с JSON

Формат Slim Select полностью совместим с JSON.

Это позволяет:

  • хранить конфигурации на сервере;
  • передавать данные через REST API;
  • использовать localStorage;
  • кешировать списки;
  • динамически генерировать select.

Пример JSON:

[
  {
    "text": "JavaScript",
    "value": "js"
  }
]

Типизация формата данных

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


Интерфейс опции

interface SlimOption {
  text: string
  value: string | number
  selected?: boolean
  disabled?: boolean
  html?: string
}

Интерфейс группы

interface SlimGroup {
  label: string
  options: SlimOption[]
}

Практическая схема организации данных

Для крупных приложений часто применяется разделение:

const selectData = {
  countries: [],
  cities: [],
  users: [],
  roles: []
}

После загрузки:

slim.setData(selectData.countries)

Такой подход упрощает:

  • повторное использование;
  • кеширование;
  • синхронизацию;
  • lazy loading;
  • обновление интерфейса.