Переупорядочить список опций выбора с помощью Vanilla JS

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

Моя идея заключалась в том, чтобы найти любой вариант, в котором есть «Нет в наличии», затем добавить класс с именем outOfStock и переместить его в конец списка. Чтобы попытаться сделать это, я создал значение данных для каждого продукта, используя его innerHTML и поиск значения «Нет в наличии», но это работает, только если у меня есть полное значение данных в запросе. Есть ли способ найти все значения данных, у которых нет на складе? Или есть другое решение, которое вы могли бы предложить, чтобы я мог переместить товары, которых нет в наличии, в конец списка вариантов? Любая помощь будет оценена

for (const element of document.querySelectorAll(".form-dropdown option")) {
  element.dataset.product = element.innerHTML;
}

document.querySelector(".form-dropdown option[data-product='Cherry - Out of stock']").classList.add('outOfStock');
<select class="form-dropdown">
<option disabled="" value="">Choose option</option>
<option value="0">Apple</option>
<option value="1">Banana</option>
<option value="2">Cherry - Out of stock</option>
<option value="3">Kiwi</option>
<option value="4">Lemon - Out of stock</option>
<option value="5">Melon - Out of stock</option>
<option value="6">Watermelon</option>
</select>


person leek1234    schedule 28.04.2021    source источник
comment
Как это? jsfiddle.net/jktdmvwg   -  person Chris G    schedule 28.04.2021
comment
@ChrisG Да, это именно то, что я ищу. Спасибо за это!!   -  person leek1234    schedule 28.04.2021


Ответы (3)


Я просмотрел кучу дубликатов, таких как это, но мне не очень понравились ответы, поэтому я пишу свой собственный.

Самый простой способ — удалить рассматриваемые параметры, а затем добавить их снова. Это переместит их в конец, по порядку.

Вот пример кода:

document.querySelectorAll('.form-dropdown').forEach(function(select) {
  Array.from(select.options).forEach(function(option) {
    if (option.innerText.includes("Out of stock")) {
      select.removeChild(option);
      select.appendChild(option);
      option.setAttribute("disabled", true);
    }
  });
});
<select class="form-dropdown">
  <option disabled="" value="">Choose option</option>
  <option value="0">Apple</option>
  <option value="1">Banana</option>
  <option value="2">Cherry - Out of stock</option>
  <option value="3">Kiwi</option>
  <option value="4">Lemon - Out of stock</option>
  <option value="5">Melon - Out of stock</option>
  <option value="6">Watermelon</option>
</select>

person Chris G    schedule 28.04.2021

Лучший способ сделать это — отсортировать элементы, прежде чем добавлять их в виде HTML, но здесь я удалил их из HTML, затем отсортировал, а затем повторно применил tp HTML.

for (const element of document.querySelectorAll(".form-dropdown option")) {
  element.dataset.product = element.innerHTML;
}

document.querySelector(".form-dropdown option[data-product='Cherry - Out of stock']").classList.add('outOfStock');

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

const options = document.querySelectorAll('option');

const sortOptions = [];

      options.forEach(option => sortOptions.push(option));
      
      sortOptions.sort((a,b) => a.innerHTML.indexOf('- Out') > -1 ? -1 : 1);
      
      select.innerHTML = '';
     
      sortOptions.forEach(option => select.appendChild(option));
<select class="form-dropdown">
<option disabled="" value="">Choose option</option>
<option value="0">Apple</option>
<option value="1">Banana</option>
<option value="2">Cherry - Out of stock</option>
<option value="3">Kiwi</option>
<option value="4">Lemon - Out of stock</option>
<option value="5">Melon - Out of stock</option>
<option value="6">Watermelon</option>
</select>

person user3094755    schedule 28.04.2021

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

<!DOCTYPE html>
<html lang="en">
<head></head>
<body>
    <select class="form-dropdown">
        <option disabled="" value="">Choose option</option>
    </select>
    <script>
        let products = [
            {name: "Apple", inStock: true},
            {name: "Banana", inStock: true},
            {name: "Cherry", inStock: false},
            {name: "Kiwi", inStock: true},
            {name: "Lemon", inStock: false},
            {name: "Melon", inStock: false},
            {name: "Watermelon", inStock: true}
        ]

        products.sort((a, b) => {
            if(a.inStock) {
                return -1
            }
        })

        var menu = (document.getElementsByClassName("form-dropdown"))[0]

        products.forEach(item => {
            var opt = document.createElement("option")
            opt.value = item.name

            if(item.inStock) opt.text = item.name
            else opt.text = item.name + " - Out of Stock"

            menu.add(opt)
        })
    </script>
</body>
</html>

person almarc    schedule 28.04.2021
comment
Ваш код не перемещает продукты, которых нет в наличии, в конец. - person Chris G; 28.04.2021