select в JavaScript

Элемент select позволяет выбрать один или несколько вариантов из списка. В JavaScript через него можно получить текущее значение, изменить выбор, обработать действия пользователя, а также добавить или удалить пункты.

Для обычного списка выбранное значение находится в свойстве value:

const select = document.querySelector('select');

console.log(select.value);

Разметка select

Создадим список для выбора города:

<form class="city-form">
  <label for="city">Город</label>

  <select id="city" name="city">
    <option value="" selected>Выберите город</option>
    <option value="moscow">Москва</option>
    <option value="kazan">Казань</option>
    <option value="samara">Самара</option>
  </select>
</form>

Элемент select представляет весь список, а каждый option - отдельный вариант. Атрибут value содержит значение для JavaScript и данных формы, а текст между тегами видит пользователь.

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

<option value="kazan">Казань</option>

Пользователь видит «Казань», а JavaScript получает строку ‘kazan’. Если не указать value, значением станет текст пункта. Явный атрибут обычно удобнее: отображаемую подпись можно изменить, не затрагивая данные.

Атрибут name понадобится при отправке формы. Связанные значения for=“city” и id=“city” соединяют список с подписью.

Как получить значение select

Найдём список и обратимся к свойству value:

const citySelect = document.querySelector('#city');
const city = citySelect.value;

console.log(city); // пустая строка

В начальной разметке выбран пункт «Выберите город» с value="", поэтому результатом будет пустая строка. После выбора Казани свойство вернёт ‘kazan’.

value всегда возвращает строку. Если значения пунктов нужны для вычислений, их следует преобразовать в числа:

<select class="quantity">
  <option value="1">Один товар</option>
  <option value="2">Два товара</option>
  <option value="3">Три товара</option>
</select>
const quantitySelect = document.querySelector('.quantity');
const quantity = Number(quantitySelect.value);

console.log(quantity); // 1
console.log(typeof quantity); // number

Как получить выбранный option

Свойство value возвращает данные выбранного пункта. Если нужен сам элемент option, можно использовать selectedIndex и коллекцию options:

const selectedIndex = citySelect.selectedIndex;
const selectedOption = citySelect.options[selectedIndex];

console.log(selectedIndex); // 0
console.log(selectedOption.value); // пустая строка
console.log(selectedOption.textContent); // Выберите город

selectedIndex содержит индекс выбранного пункта, а options - все элементы option внутри списка. Индексы начинаются с нуля.

Если в списке ничего не выбрано, selectedIndex будет равен -1. Тогда обращение citySelect.options[-1] вернёт undefined. Получить выбранный элемент с проверкой можно через коллекцию selectedOptions:

const selectedOption = citySelect.selectedOptions[0];
const selectedText = selectedOption?.textContent ?? '';

console.log(selectedText);

У обычного select в selectedOptions находится один элемент. Эта же коллекция понадобится для списка, который разрешает выбрать несколько вариантов.

Как изменить выбранное значение

Выбрать пункт из JavaScript можно присваиванием нового value:

citySelect.value = 'kazan';

console.log(citySelect.value); // kazan
console.log(citySelect.selectedIndex); // 2

Браузер найдёт option с value=“kazan” и сделает его выбранным. Такой код не зависит от положения пункта в списке.

Если присвоенное значение не совпадает ни с одним option, выбор будет снят:

citySelect.value = 'perm';

console.log(citySelect.value); // пустая строка
console.log(citySelect.selectedIndex); // -1

Выбор также можно изменить по индексу:

citySelect.selectedIndex = 3;

console.log(citySelect.value); // samara

Присваивание по индексу подходит, когда важно положение пункта. В остальных случаях value обычно понятнее и надёжнее: добавление нового option выше выбранного изменит индексы.

Ещё один способ - изменить свойство selected у конкретного элемента:

const moscowOption = citySelect.querySelector(
  'option[value="moscow"]',
);

moscowOption.selected = true;

Обработка изменения select

Событие change происходит после того, как пользователь выбирает другой пункт. В обработчике уже доступны новое значение и выбранный option.

<p class="city-result" aria-live="polite"></p>
const cityResult = document.querySelector('.city-result');

citySelect.addEventListener('change', function (event) {
  const currentSelect = event.currentTarget;
  const selectedOption = currentSelect.selectedOptions[0];

  cityResult.textContent = currentSelect.value === ''
    ? 'Город не выбран'
    : 'Выбран город: ' + selectedOption.textContent;
});

event.currentTarget указывает на select, которому назначен обработчик. Через currentSelect.value код получает значение, а через выбранный option - текст для пользователя.

Присваивание citySelect.value = ‘kazan’ из JavaScript само по себе не вызывает change. Если после программного выбора нужно обновить интерфейс, вызовите отвечающую за это функцию отдельно.

Работа с коллекцией options

Свойство options содержит живую коллекцию всех пунктов списка. Через неё можно узнать количество вариантов и перебрать их:

console.log(citySelect.options.length); // 4

for (const option of citySelect.options) {
  console.log(option.value, option.textContent, option.selected);
}

У каждого option есть собственные свойства:

  • value - значение пункта;
  • textContent - отображаемый текст;
  • selected - выбран ли пункт;
  • disabled - недоступен ли он для выбора.

Коллекция является живой: если добавить или удалить option, её состав и length обновятся автоматически.

Добавление и удаление option

Новый пункт можно создать обычным DOM-методом createElement(), заполнить и добавить в список:

const newOption = document.createElement('option');

newOption.value = 'perm';
newOption.textContent = 'Пермь';

citySelect.append(newOption);

После выполнения кода новый пункт появится в конце списка. Если он должен сразу стать выбранным, можно задать selected:

newOption.selected = true;

Для удаления найдём нужный option по значению и вызовем remove():

const samaraOption = citySelect.querySelector(
  'option[value="samara"]',
);

samaraOption?.remove();

Если удалён выбранный пункт, браузер обновит состояние списка. Поэтому при необходимости сразу проверьте новое значение citySelect.value и обновите связанную часть интерфейса.

Множественный выбор

Атрибут multiple разрешает выбрать несколько пунктов. На компьютере пользователь обычно делает это с помощью клавиш Ctrl или Cmd, а внешний вид и способ выбора зависят от браузера и устройства.

<form class="skills-form">
  <label for="skills">Навыки</label>

  <select id="skills" name="skills" multiple size="4">
    <option value="html">HTML</option>
    <option value="css">CSS</option>
    <option value="javascript">JavaScript</option>
    <option value="git">Git</option>
  </select>
</form>

У такого списка свойство value возвращает только значение первого выбранного пункта. Чтобы получить все значения, используют selectedOptions:

const skillsSelect = document.querySelector('#skills');

const selectedSkills = [...skillsSelect.selectedOptions].map(
  function (option) {
    return option.value;
  },
);

console.log(selectedSkills); // например, ['html', 'javascript']

selectedOptions возвращает коллекцию выбранных элементов. Spread-оператор ... преобразует её в массив, а map() собирает значения.

Выбрать несколько пунктов из JavaScript можно через свойство selected каждого option:

const requiredSkills = ['css', 'javascript'];

for (const option of skillsSelect.options) {
  option.selected = requiredSkills.includes(option.value);
}

FormData и обязательный выбор

При сборе формы через FormData значение обычного select получают по его атрибуту name:

<form class="profile-form">
  <label for="country">Страна</label>

  <select id="country" name="country" required>
    <option value="">Выберите страну</option>
    <option value="ru">Россия</option>
    <option value="by">Беларусь</option>
    <option value="kz">Казахстан</option>
  </select>

  <button type="submit">Сохранить</button>
</form>
const profileForm = document.querySelector('.profile-form');

profileForm.addEventListener('submit', function (event) {
  event.preventDefault();

  const formData = new FormData(profileForm);
  const country = formData.get('country');

  console.log(country); // ru, by или kz
});

Атрибут required не позволит отправить форму, пока выбран пункт с пустым value. Если у select нет name, его значение не попадёт в FormData.

Для списка с multiple в данные попадает каждое выбранное значение под одним именем. Их получают методом getAll():

const skillsForm = document.querySelector('.skills-form');
const formData = new FormData(skillsForm);
const skills = formData.getAll('skills');

console.log(skills); // например, ['html', 'javascript']

Чтобы значения попали в FormData, список должен быть связан с формой и иметь атрибут name. Если форма не нужна, выбранные значения можно получить напрямую через selectedOptions.

Начальное состояние и сброс формы

Атрибут selected у option задаёт начальный выбор. Текущее состояние находится в DOM-свойстве option.selected, а начальное - в option.defaultSelected.

const firstOption = citySelect.options[0];

console.log(firstOption.selected); // текущее состояние
console.log(firstOption.defaultSelected); // true

После выбора другого города свойство selected у первого пункта станет равным false, а defaultSelected сохранит начальное значение.

Если select находится внутри формы, метод reset() вернёт его к варианту, отмеченному атрибутом selected:

const form = citySelect.form;

form.reset();

Итого

Свойство select.value содержит значение выбранного пункта, selectedIndex - его индекс, а selectedOptions - коллекцию выбранных элементов. Изменить выбор можно через value, selectedIndex или свойство option.selected.

Событие change подходит для реакции на выбор пользователя. Все пункты доступны в живой коллекции options, а для списка с multiple значения собирают из selectedOptions или получают через FormData.getAll().