Как создать свой Select на CSS и JavaScript?

Александр Мальцев
Александр Мальцев
23K
34
Как создать свой Select на CSS и JavaScript?
Содержание:
  1. Зачем разрабатывать свой Select, если есть тег <select>
  2. Подключение и использование компонента Select
  3. Как использовать компонент CustomSelect
  4. Как устроен компонент Select
  5. Комментарии

В этой статье разберём, как, используя CSS и JavaScript, написать свою реализацию компонента, который будет очень похож по функционалу на элемент интерфейса, создаваемого с помощью стандартного HTML тега <select>.

Зачем разрабатывать свой Select, если есть тег <select>

При создании селекта с помощью стандартного HTML-элемента <select>, мы ограничены в его изменении. Т.к. не всегда можем его настроить и стилизовать так, как нам это необходимо в том или ином случае.

В таких ситуациях в большинстве случаев будет более грамотно написать свою реализацию селекта с нужной логикой и оформлением.

В этой статье мы рассмотрим процесс создания своего Select с функционалом, который позволит пользователю выбирать одно из нескольких значений, представленных в выпадающем списке.

Вид селекта, спроектированного на чистом CSS и JavaScript, в закрытом состоянии Вид селекта, спроектированного на чистом CSS и JavaScript, в открытом состоянии

При необходимости в дальнейшем этот функционал можно будет доработать под те задачи, которые перед нами будут стоять. Вообще в веб-разработке создание выпадающего меню – это одна из наиболее частых задач. Разберём как её можно реализовать посредством CSS и JavaScript.

Подключение и использование компонента Select

Исходные коды разработанного компонента Select расположены на Github. Написан он с использованием CSS и чистого JavaScript. Зависимостей от jQuery и каких-либо других js-плагинов нет.

Для подключения компонента к странице достаточно к ней просто подключить CSS и JavaScript файл этого компонента или поместить эти коды в соответствующие свои файлы.

<!-- подключаем CSS селекта -->
<link rel="stylesheet" href="custom-select.css">

<!-- подключаем JS селекта -->
<script src="custom-select.js"></script>

Как использовать компонент CustomSelect

Компонент CustomSelect можно использовать на странице 2 способами.

Первый способ подразумевает непосредственную вставку HTML-кода селектора на страницу:


<div class="select" id="select-1">
  
  <button type="button" class="select__toggle" name="car" value="" data-select="toggle" data-index="-1">Выберите из списка</button>
  
  <div class="select__dropdown">
    <ul class="select__options">
      <li class="select__option" data-select="option" data-value="volkswagen" data-index="0">Volkswagen</li>
      <li class="select__option" data-select="option" data-value="ford" data-index="1">Ford</li>
      <li class="select__option" data-select="option" data-value="toyota" data-index="2">Toyota</li>
      <li class="select__option" data-select="option" data-value="nissan" data-index="3">Nissan</li>
    </ul>
  </div>
</div>

Элемент <button> представляет собой кнопку, предназначенную для открытия выпадающего списка. Её действие в JavaScript коде определяется с помощью атрибута data-select="toggle".

Также кнопка содержит пару «имя=значение» (где значение – это значение выбранной опции). Имя устанавливается атрибутом name, а значение – value. Поэтому если CustomSelect поместить в форму, то значение выбранной опции вместе с другими данными будут отправлены на сервер.

data-index содержит индекс выбранной опции. Если по умолчанию не должна быть установлена какая-то опция, то атрибуту value следует задать пустую строку, а data-index – значение -1.

В select__options находятся опции: <li> с классом select__option. data-select="option" определяет действие аналогично с кнопкой, data-value – значение опции, а data-index – её индекс (порядковый номер).

Если изначально какая-то опция должна быть активна, то к ней необходимо добавить класс select__item_selected. А также поместить в кнопку: в value – её значение, в data-index – её индекс, в содержимое – её контент.


<div class="select" id="select-1">
  <button type="button" class="select__toggle" name="car" value="ford" data-select="toggle" data-index="1">Выберите из списка</button>
  <div class="select__dropdown">
    <ul class="select__options">
      <li class="select__option" data-select="option" data-value="volkswagen" data-index="0">Volkswagen</li>
      <li class="select__option select__option_selected" data-select="option" data-value="ford" data-index="1">Ford</li>
      <li class="select__option" data-select="option" data-value="toyota" data-index="2">Toyota</li>
      <li class="select__option" data-select="option" data-value="nissan" data-index="3">Nissan</li>
    </ul>
  </div>
</div>

После создания необходимой HTML-структуры необходимо активировать корневой элемент (.select) как CustomSelect с помощью JavaScript.

Выполняется это следующим образом:

// #select-1 - селектор для выбора элемента, который необходимо инициализировать как CustomSelect
const select1 = new CustomSelect('#select-1');

Второй способ предполагает использование CustomSelect без необходимости непосредственной вставки HTML-структуры компонента на страницу. Здесь достаточно лишь поместить контейнер (пустой элемент) в HTML-документ.

<div id="select-2"></div>

Варианты и дефолтный текст (начальное значение) селекту необходимо передать при создании объекта в виде аргумента.

const select2 = new CustomSelect('#select-2', {
  name: 'car', // значение атрибута name у кнопки
  targetValue: 'ford', // значение по умолчанию
  options: [['volkswagen', 'Volkswagen'], ['ford', 'Ford'], ['toyota', 'Toyota'], ['nissan', 'Nissan']], // опции
});

Значение options - это массив массивов. Первый элемент массива – это значение опции, а второй – её текстовое представление.

Если не нужно чтобы CustomSelect имел какое-то значение по умолчанию, то установите ключу targetValue пустую строку или вообще его не указывайте:

const select2 = new CustomSelect('#select-2', {
  name: 'car', // значение атрибута name у кнопки
  options: [['volkswagen', 'Volkswagen'], ['ford', 'Ford'], ['toyota', 'Toyota'], ['nissan', 'Nissan']], // опции
});

После инициализации селекта, доступны следующие свойства и методы:

  • value – позволяет как получить выбранную опцию, так и установить её;
  • selectedIndex – индекс выбранного элемента (нумерация начинается с 0);
  • show() – показывает выпадающий список с опциями;
  • hide() – скрывает dropdown меню;
  • toggle() – переключает видимость выпадающего меню;
  • dispose() - удаляет обработчики событий, связанных с этим селектом.

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

// установим в качестве выбранной опции элемент со значением toyota
select2.value = 'toyota';
// получим значение выбранной опции
console.log( select2.value ); // toyota

Кроме этого value позволяет также сбросить выбранную опцию. Для этого value нужно установить пустую строку или значение не соответствующее ни одной из опций:

// сбросим выбранную опцию
select2.value = '';

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

// установим в качестве выбранной опции элемент с индексом 2
select2.selectedIndex = 2;
// получим индекс выбранной опции
console.log( select2.selectedIndex );

Если ни один из элементов не выбран, то selectedIndex возвращает -1:

select2.value = '';
// получим индекс выбранного элемента
console.log( select2.selectedIndex ); // -1

Сбросить выбранный элемент можно не только посредством value, но также, если установить selectedIndex число -1 или индекс элемента, которого нет:

select2.selectedIndex = -1;

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

document.querySelector('#select-2').addEventListener('select.change', (e) => {
  const btn = e.target.querySelector('.select__toggle');
  // выбранное значение
  console.log(`Выбранное значение: ${btn.value}`);
   // индекс выбранной опции
  console.log(`Индекс выбранной опции: ${btn.dataset.index}`);
  // выбранный текст опции
  const selected = e.target.querySelector('.select__option_selected');
  const text = selected ? selected.textContent : '';
  console.log(`Выбранный текст опции: ${text}`);
});

Кроме как использовать событие, это действие также можно выполнить с помощью метода onSelected при создании экземпляра объекта CustomSelect:

2 способ (через метод onSelect):

new CustomSelect('#select-2', {
  name: 'car',
  targetValue: 'ford',
  data: [['volkswagen', 'Volkswagen'], ['ford', 'Ford'], ['toyota', 'Toyota'], ['nissan', 'Nissan']],
  onSelected(select, option) {
    // выбранное значение
    console.log(`Выбранное значение: ${select.value}`);
    // индекс выбранной опции
    console.log(`Индекс выбранной опции: ${select.selectedIndex}`);
    // выбранный текст опции
    const text = option ? option.textContent : '';
    console.log(`Выбранный текст опции: ${text}`);
  }
});

Как устроен компонент Select

Компонент Select построен с использованием HTML, CSS и JavaScript.

HTML код компонента Select:

<div class="select">
  <button type="button" class="select__toggle" name="car" value="" data-select="toggle" data-index="-1">Выберите из списка</button>
  <div class="select__dropdown">
    <ul class="elect__options">
      <li class="elect__option" data-select="option" data-value="volkswagen" data-index="0">Volkswagen</li>
      <li class="elect__option elect__option_selected" data-select="option" data-value="ford" data-index="1">Ford</li>
      <li class="elect__option" data-select="option" data-value="toyota" data-index="2">Toyota</li>
    </ul>
  </div>
</div>

Элемент с классом select определяет этот компонент. В нём находится вся HTML-структура селекта. Тег <button> с классом select__toggle и атрибутами data-select="toggle", data-index предназначен для отображения выбранного значения и открытия при нажатии на него выдающего списка с опциями. Само выпадающее меню реализовано посредством элемента select__dropdown. Оно с помощью CSS настраивается так, чтобы оно было расположено под <button>. Список вариантов (.select__options) организован посредством маркированного списка. Выбранный элемент в нём отмечается посредством добавления к нему класса select__option_selected.

Кроме непосредственной вставки HTML кода на страницу, предоставим также возможность создавать его автоматически с помощью JavaScript. Таким образом, на страницу будет достаточно поместить пустой элемент и инициализировать его как CustomSelect. Как устроен JavaScript код приведём ниже.

Классы элементов будем использовать в CSS для добавления к ним стилей, а data атрибуты - в JavaScript.

CSS стили компонента Select можно посмотреть на GitHub.

Для обёртки установлено относительное позиционирование. Это необходимо для того, чтобы выпадающее меню можно было позиционировать относительно неё.

.select {
  position: relative;
  ...
}

Элемент с классом select__toggle стилизуем в виде кнопки (текущий вариант в ней будем выводить как её содержимое).

.select__toggle {
  display: flex;
  background-color: #fff;
  border: 1px solid #ccc;
  border-radius: 0.3125rem;
  cursor: pointer;
  align-items: center;
  width: 100%;
  font-size: 1rem;
  padding: 0.375rem 0.75rem;
  line-height: 1.4;
  user-select: none;
  font-size: 1rem;
  justify-content: space-between;
  font-style: italic;
}

Иконку к кнопке добавим через псевдоэлемент ::after:

.select__toggle::after {
  content: '';
  width: 0.75rem;
  height: 0.75rem;
  background-size: cover;
  background-image: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" height="100" width="100"%3E%3Cpath d="M97.625 25.3l-4.813-4.89c-1.668-1.606-3.616-2.41-5.84-2.41-2.27 0-4.194.804-5.777 2.41L50 52.087 18.806 20.412C17.223 18.805 15.298 18 13.03 18c-2.225 0-4.172.804-5.84 2.41l-4.75 4.89C.813 26.95 0 28.927 0 31.23c0 2.346.814 4.301 2.439 5.865l41.784 42.428C45.764 81.174 47.689 82 50 82c2.268 0 4.215-.826 5.84-2.476l41.784-42.428c1.584-1.608 2.376-3.563 2.376-5.865 0-2.26-.792-4.236-2.375-5.932z"/%3E%3C/svg%3E');
}

По умолчанию dropdown меню не будет показываться. Включение его отображения будем осуществлять посредством добавления к нему класса select_show:

.select_show .select__dropdown {
  display: block;
}

При этом при показе dropdown меню иконку будем поворачивать на 180 градусов посредством CSS трансформации:

.select_show .select__toggle::after {
  transform: rotate(180deg);
}

CSS код для стилизации dropdown меню:

.select__dropdown {
  display: none;
  position: absolute;
  top: 2.5rem;
  left: 0;
  right: 0;
  border: 1px solid #ccc;
  max-height: 10rem;
  overflow-y: auto;
  border-radius: 0.3125rem;
}
.select__options {
  margin: 0;
  padding: 0;
  list-style: none;
}
.select__option {
  padding: 0.375rem 0.75rem;
}

Стилизация при наведении на пункт меню:

.select__option:hover {
  background-color: #f5f5f5;
  cursor: pointer;
  transition: 0.2s background-color ease-in-out;
}

JavaScript код компонента доступен на GitHub. Его можно открыть, используя эту ссылку.

Код написан с использованием класса:


class CustomSelect {
  ...
}

Свойства и методы, которые не нужно использовать вне класса, начинаются с нижнего подчеркивания:

class CustomSelect {
  constructor(target, params) {
    this._elRoot = typeof target === 'string' ? document.querySelector(target) : target;
    ...
  }
  ...
  _onClick(e) { ... }
  ...
}

Подчеркивание перед именем — это общепринятое соглашение для именования свойств и методов, которые используются только внутри класса, обращаться к ним вне его не нужно.

Структура JavaScript кода:

class CustomSelect {
  constructor(target, params) { }
  // обработчик события click
  _onClick(e) { }
  // сбрасывает состояние, генерирует событие 'select.change'
  _reset() { }
  // обновляет значения атрибутов в зависимости от выбранной опции, генерирует событие 'select.change'
  _update(option) { }
  // при изменении выбранной опции
  _changeValue(option) { }

  // включает отображение выпадающего списка
  show() { }
  // скрывает список с опциями
  hide() { }
  // переключает список с опциями
  toggle() { }
  // удаления слушателей события click селекта
  dispose() { }
  // возвращает значение выбранной опции
  get value() { }
  // позволяет установить опцию по значению
  set value(value) { }
  // возвращает индекс выбранной опции
  get selectedIndex() { }
  // позволяет выбрать опцию по её индексу
  set selectedIndex(index) { }
}
// функция для генерации HTML-кода селекта в зависимости от переданных аргументов
CustomSelect.template = params => { };
// для закрытия открытого селекта при клике вне его
document.addEventListener('click', (e) => {
  if (!e.target.closest('.select')) {
    document.querySelectorAll(SELECTOR_ACTIVE).forEach(select => {
      select.classList.remove(CLASS_NAME_ACTIVE);
    });
  }
});

Комментарии:

  1. cushhy
    cushhy
    30.04.2022, 23:07
    Доброго времени, спасибо за данный селект, но я начинающий, и вообще не разбираюсь в JS. Прошу помогите мне) У меня на сайте есть калькулятор, состоит он из ползунка, который дает выбрать площадь( сайт по натяжке потолков ), далее идет три селекта, материал, количество люстр, и количество ламп. Вот мне нужно сделать калькулятор, чтобы при выборе опции из селекта, стоимость сразу шла в общую и суммировалась( а еще нужно чтобы площадь умножалась на стоимость материала ), как это сделать я понимаю на словах, но отобразить в коде не могу(. Я буду примерно благодарен, если поможете, заранее спасибо))) Если потребуется код, прислать смогу.
    1. agat
      agat
      25.04.2022, 18:16
      Здравствуйте, Александр! Очень классная статья! Спасибо)
      Подскажите, как добавить обработчик события по клику на выбираемый элемент выпадающего списка?

      Моя задача — сделать так, чтобы при клике на выбранный элемент выпадающего списка открывался соответствующий таб. Функцию открытия соответствующего таба я написал, а вот как теперь привязать элемент списка к табу… пока не знаю…
      1. Александр Мальцев
        Александр Мальцев
        26.04.2022, 10:12
        Здравствуйте! Спасибо!
        Для этого можно использовать событие select.change:
        document.querySelector('.select').addEventListener('select.change', (e) => {
          // ...
        }
        1. agat
          agat
          26.04.2022, 10:45
          Спасибо! Буду пробовать)
      2. Heitz
        Heitz
        30.01.2022, 20:06
        Сколько же соплей летело по стенам, когда я месяц делал свой первый кастомный селект )… потом загуглил и нащёл это ) и вся боль в том, что он похож на мой практически идеально, вплодь до названия css классов…
        1. Myshynov
          Myshynov
          22.01.2022, 11:07
          Здраствуйте Александр! Спасибо вам за проделанную работу. Отличная реализация кастомных селектов!

          У меня возникла небольшая проблема.
          Дело в том что в моём списке используются стили и обвертки в «span». Если назначить одну из опций по умолчанию то всё ОК и спаны с классами и стилями выводятся в кнопку. Но как только выбираешь из списка другую опцию в кнопке отображается строка без «span».
          Вот пример кода чтобы вам было проще меня понять

          const registrationSelect = new CustomSelect('#registration-select', {
            name: 'registration', // значение атрибута name у кнопки
            targetValue: 'RegularRegistration', // значение по умолчанию
            options: [
              ['RegularRegistration', 'Regular Registration <span class="price">($35.00)</span> <span class="sub-name">Breakfast pastries and refreshments included</span>'],
              ['RegularRegistration2', '2Regular Registration <span class="price">($35.00)</span> <span class="sub-name">Breakfast pastries and refreshments included</span>'],
              ['RegularRegistration3', '3Regular Registration <span class="price">($35.00)</span> <span class="sub-name">Breakfast pastries and refreshments included</span>'],
              ['RegularRegistration4', '4Regular Registration <span class="price">($35.00)</span> <span class="sub-name">Breakfast pastries and refreshments included</span>']
            ], // опции
          });
          1. Myshynov
            Myshynov
            22.01.2022, 11:29
            Я 2 дня не находил себе места перечитывал статью и все комментарии.
            И как только я написал вопрос я нашел путь к ответу. Если вдруг кто-то столкнется с таким же вопросом то вот решение. Найди верхнюю строку и замени в ней .textContent на .innerHTML:
            this._elToggle.textContent = option.textContent;
            this._elToggle.innerHTML = option.innerHTML;
            Только заметил что в самом вопросе не отобразились «span». они у меня были в значении «options»
            1. Александр Мальцев
              Александр Мальцев
              23.01.2022, 14:20
              Привет! Спасибо за отзыв! Рад, что кастомный селект понравился.
              Необходимо добавить ещё в начало метода _update следующую строчку (на Github обновил этот момент):
              _update(option) {
                option = option.closest('.select__option'); // добавить эту строчку
                // ...
              }
          2. Юрий
            Юрий
            04.12.2021, 15:43
            Здравствуйте, спасибо за плагин!!!
            Столкнулся с несколькими проблемами.
            Проект разрабатываю на Laravel.
            Первая проблема — при отправке данных на бэк, данные селектов не приходят, несмотря на наличие атрибута name и значения, но эту проблему обошел путем добавления hidden input и дальнейшего добавления в него выбранных данных при помощи js.
            Вторая проблема — есть форма с двумя селектами, которая заполняется пользователем поэтапно. Есть кнопки prev и next, при нажатии next блок с первым селектом (data-block=«1») скрывается и ajax-запросом получаются подкатегории выбранной в первом блоке категории, и на основании ответа во втором блоке (data-block=«2») создается новый селект с подкатегориями, после чего отображается второй блок.

            html код
            
            <div class="form-group" data-block="1">
                                    <div class="select" id="category-select">
                                        <button type="button" class="select__toggle" id="category_id-btn" name="category_id-btn" value=""
                                                data-select="toggle" data-index="-1">
                                            Выберите категорию
                                        </button>
                                        <div class="select__dropdown">
                                            <ul class="select__options">
                                                @php $index = 0; @endphp
                                                @foreach($categories as $category)
                                                    <li class="select__option" data-select="option" data-value="{{ $category->id }}"
                                                        data-index="{{ $index++ }}">{{ $category->name }}</li>
                                                @endforeach
                                            </ul>
                                        </div>
                                    </div>
                                    <input type="hidden" name="category_id" id="category_id">
                                </div>
                                <div class="form-group" data-block="2">
                                    <div class="select" id="service-select"></div>
                                    <input type="hidden" name="service_id" id="service_id">
                                </div>
            


            js код
            
            let serviceSelect = new CustomSelect('#service-select', {
                                                name: 'service_id-btn',
                                                options
                                            });
            
            Суть проблемы — при первом отображении второго селекта все работает, но когда нажимаю кнопку prev, скрываю второй селект, перехожу на первый, выбираю новую категорию и перехожу обратно на второй селект, html код с новыми подкатегориями формируется, НО при клике на селект не открывается дропдаун с подкатегориями, если еще раз вернусь назад, выбираю другую категорию, и перехожу снова на второй селект, дропдаун уже открывается, но при выборе нужной подкатегории он уже не закрывается.
            1. Александр Мальцев
              Александр Мальцев
              07.12.2021, 15:17
              Привет!
              Вот пример состоящий из 2 селектов. Может он поможет. В нём при выборе элемента из 1 селекта, второй наполняется данными посредством AJAX в зависимости от значения первого селекта.
            2. Gregory
              Gregory
              01.11.2021, 15:54
              1 — поставьте пожалуйста кнопку для комментария в начале списка комментариев, а то пригодится листать в самый низ списка комментов
              2 — в начале скрипта вы определяете константы вне класса, вне конструктора. Это для каких целей делается?
              1. Gregory
                Gregory
                01.11.2021, 12:13
                Небольшая модификация CSS для мобильных — может пригодится

                @media (max-width: 500px) {
                  .select__options{
                    position: fixed;
                    height: 100%;
                    overflow-y: scroll;
                    top: 0;
                    left: 0;
                    background: white;
                    width: 100vw;
                    padding: 20px;
                  }
                }
                1. Gregory
                  Gregory
                  01.11.2021, 12:28
                  да вот ещё
                  
                  * {
                        box-sizing: border-box;
                  }
                  
                2. Александр
                  Александр
                  14.10.2021, 12:46
                  Александр, добрый день. Имеется ли возможность задавать разные значения переменной
                  selectedContent
                  для разных селектов. По умолчанию стоит 'Выберите из списка';
                  1. Daniel
                    Daniel
                    29.09.2021, 10:04
                    Здраствуйте Александр. Большое спасибо за разработанный плагин CustomSelect, отличная работа. сэкономлено кучу времени. У меня возник один вопрос: на базе вашего плагина пишу калькулятор и столкнулся с небольшой проблемой, а именно: создаю функцию Reset для сброса всех значений «name», «value» в дефолтное состояние но при клике на кнопке reset не получаю никакого результата.
                    Вот пример кода:
                    function resetBtn() {
                      let btnReset = document.queryselectorAll("select-reset");
                      btnReset.value = "" ;
                      btnRest. name = "" ;
                    };
                    <button type="reset" onClick="resetBtn()">Reset</button>
                    Буду очень благодарен за помощь. Спасибо.
                    1. Александр Мальцев
                      Александр Мальцев
                      29.09.2021, 14:20
                      Добрый день! Наверно так:
                      function resetBtn() {
                        let btnReset = document.querySelectorAll('.select-reset');
                        btnReset.forEach((element) => {
                          element.value = '';
                          element.name = '';
                        });
                      }
                      Не знаю, что такое select-reset? Класс?
                      После того как выбрали элементы с помощью querySelectorAll, их нужно перебрать, например, с помощью forEach. Так напрямую нельзя.
                      1. Daniel
                        Daniel
                        29.09.2021, 14:46
                        Большое спасибо за столь быстрый ответ. да, select-reset это я добавил некий клас, для сброса значений и в калькуляторе я использую несколько CustomSelect и радио-кнопки checkbox. ok, попробую с forEach. Ещё раз спасибо. Хорошего дня
                    2. Daria
                      Daria
                      20.08.2021, 18:19
                      Здравствуйте, Александр, спасибо вам за проделанную работу, ваш селект прекрасен))

                      у меня возникла проблема,
                      Мне нужно два селекта, они расположены рядом в форме, добавляю их Первым способом
                      все работает хорошо, кроме закрытия по клику на второй селект.

                      1) Кликаем на первый селект, ничего, не выбрано, кликаем, на второй селект, первый остается в открытом состоянии, но не активен при ховере, если кликнуть «оживает», получается два открытых одновременно селекта.

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

                      1. Александр Мальцев
                        Александр Мальцев
                        21.08.2021, 12:04
                        Привет! Спасибо за отзыв. Переписал код компонента, а также исправил этот баг. Также изменил название классов и атрибутов, поэтому обратите на это внимание при обновлении кода.
                      2. Кирилл
                        Кирилл
                        18.08.2021, 18:13
                        Верно ли понимаю, что мы можем управлять выбором значения по индексу или названию(value), так:
                        select1.selectedItem(6); // (где 6 — это 7 элемент списка).
                        Но у меня к сожалению, так не сработало :(

                        P.S. спасибо большое за реализацию.
                        1. Александр Мальцев
                          Александр Мальцев
                          19.08.2021, 03:34
                          Нужно передавать в формате объекта:
                          // по индексу
                          select1.selectedItem({index: 0})
                          // по значению
                          select1.selectedItem({value: 'Nissan'})
                          1. Кирилл
                            Кирилл
                            19.08.2021, 09:37
                            Благодарю!
                        2. Konstantin
                          Konstantin
                          03.06.2021, 13:35
                          Может быть это у меня что то с ip, но ни одна ссылка на материалы из этого поста не открывается. Выдает 404 ошибку. в том числе на GIT!!!
                          1. Александр Мальцев
                            Александр Мальцев
                            03.06.2021, 13:50
                            Поправил ссылки.
                          2. Александр
                            Александр
                            24.11.2020, 17:07
                            Александр, здравствуйте! Спасибо, за отличный вариант и достойную альтернативу дефолтному селекту. Пытаюсь это решение использовать в сортировке mFilter2, не получается всё сделать по уму да и вообще мало что получается честно говоря, делаю так:

                            <div class="select" id="mse2_sort">
                              <div class="select__backdrop" data-select="backdrop"></div>
                              
                             <button type="button" class="select__trigger" data-select="trigger" value="asc" data-sort="resource|pagetitle" data-icon="fa-list">
                                По умолчанию
                             </button>
                            
                            <div class="select__dropdown">
                                <ul class="select__items">
                                  <li class="select__item" data-select="item"  value="asc" data-sort="extendresource|date"><i class="fa fa-play"></i>Дата</li>
                                  <li class="select__item" data-select="item" value="desc" data-sort="extendresource|size"><i class="fa fa-table"></i>Размер</li>
                                </ul>
                              </div>
                            </div>
                            <script>
                             const select1 = new CustomSelect('#mse2_sort'); 
                            </script>
                            как я понимаю, так работать не будет, так как в файле default.js в параметрах скрипта mFilter2, завязано всё на теге «a»
                            sort_link: '#mse2_sort a'
                            если изменить на тег «li», то сортировка начинает работать, но не сохраняет выбранное значение при перезагрузке страницы. Александр, если возможно расскажите пожалуйста как нужно и лучше сделать, чтобы сортировка работала и сохраняла выбранное значение при перезагрузки страницы?
                            1. Александр Мальцев
                              Александр Мальцев
                              26.11.2020, 16:53
                              Привет! Спасибо за отзыв.
                              Чтобы в mFilter2 изменить sort_link можно использовать параметр &filterOptions:
                              [[!mFilter2? 
                                ...
                                &filterOptions=`{"sort_link": "#mse2_sort li"}`
                              ]]
                              Установить выбранную сортировку в CustomSelect после перезагрузки страницы можно посредством добавления следующего скрипта на страницу:
                              <script>
                              const queryString = window.location.search;
                              const urlParams = new URLSearchParams(queryString);
                              const sort = urlParams.get('sort');
                              let value = '';
                              if (sort) {
                                const delim = sort.indexOf(':');
                                const res = delim === -1 ? sort : sort.substring(0, delim);
                                const $li = document.querySelector(`#mse2_sort li[data-sort="${res}"]`);
                                if ($li) {
                                  value = $li.textContent;
                                }
                              }
                              const select1 = new CustomSelect('#mse2_sort');
                              if (value) {
                                select1.selectedItem({value: value})
                              } 
                              </script>
                              1. Александр
                                Александр
                                26.11.2020, 20:20
                                Александр, огромное спасибо за решение, в очередной раз выручили.
                            2. Владимир
                              Владимир
                              07.11.2020, 23:40
                              Александр, еще момент.

                              1. Александр Мальцев
                                Александр Мальцев
                                08.11.2020, 07:28
                                Спасибо! Этот момент тоже доработал и обновил код js-файла на Github.
                              2. Владимир
                                Владимир
                                07.11.2020, 15:03
                                Еще момент.
                                Если создание нового экземпляра объекта CustomSelect происходит таким образом
                                const select1 = new CustomSelect(".select");
                                то в консоли получаю следующую ошибку
                                1. Александр Мальцев
                                  Александр Мальцев
                                  07.11.2020, 15:47
                                  Спасибо! Поправил код скрипта на Github.
                                2. Владимир
                                  Владимир
                                  07.11.2020, 14:58
                                  Добрый день!

                                  На странице категории есть сортировка, сделанная через стандартный select. При выборе какой-либо сортировки происходит перезагрузка страницы.

                                  Пытаюсь применить Ваш плагин. В итоге код получился такой
                                  <div class="select">
                                    <div class="select__backdrop" data-select="backdrop"></div>
                                    <button type="button" class="select__trigger" data-select="trigger">По умолчанию</button>
                                    <div class="select__dropdown">
                                      <ul class="select__items">
                                        <?php foreach ($sorts as $sorts) { ?>
                                        <?php if ($sorts['value'] == $sort . '-' . $order) { ?>
                                        <li class="select__item select__item_selected" data-select="item" data-url="<?php echo $sorts['href']; ?>"><?php echo $sorts['text']; ?></li>
                                        <?php } else { ?>
                                        <li class="select__item" data-select="item" data-url="<?php echo $sorts['href']; ?>"><?php echo $sorts['text']; ?></li>
                                        <?php } ?>
                                        <?php } ?>
                                      </ul>
                                    </div>
                                  </div>
                                  <script>
                                  const select1 = new CustomSelect(".select", { });
                                  
                                  document.querySelector(".select").addEventListener("select.change", (e) => {
                                    location = document.querySelector(".select__item_selected").getAttribute("data-url"); 
                                  });
                                  </script>
                                  Не получается подставить выбранное значение в button.
                                  Подскажите, пожалуйста, как это можно сделать?
                                  1. Александр Мальцев
                                    Александр Мальцев
                                    07.11.2020, 15:36
                                    Здравствуйте!
                                    Установите выбранное значение в button с помощью JavaScript:
                                    document.querySelector('.select__trigger').textContent = document.querySelector('.select__item_selected').textContent;
                                    
                                    1. Владимир
                                      Владимир
                                      07.11.2020, 16:01
                                      Оказалось все так просто.
                                      Спасибо, Александр!
                                  Войдите, пожалуйста, в аккаунт, чтобы оставить комментарий.