Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Как поменять последний выпадающий список на кнопку поиска? (https://javascript.ru/forum/dom-window/84179-kak-pomenyat-poslednijj-vypadayushhijj-spisok-na-knopku-poiska.html)

VampireFang 28.06.2022 21:22

Как поменять последний выпадающий список на кнопку поиска?
 
Есть готовый рабочий код. Подскажите, пожалуйста, как изменить последний выпадающий список на кнопку "найти", а так же сделать, чтобы эту кнопку можно было нажать при выборе значения хотя бы в одном выпадающем списке.
<div class="chained-selects">
  <select class="app-select form-control">
    <option selected>Выберите марку</option>
  </select>						    
  <select class="app-select form-control" disabled>
    <option selected>Выберите модель</option>
  </select>						    
  <select class="app-select form-control"disabled>
    <option selected>Выберите кузов</option>
  </select>    										    						  
</div>

const options = generateOptions();
const chainedSelects = document.querySelector(".chained-selects");
chainedSelects.addEventListener("change", onChange, false);
draw(chainedSelects.firstChild, options);

function onChange(event) {
  const { target } = event;
  let node = target, path = [];

  while (node = node.nextElementSibling) {
    node.length = 1;
    node.disabled = true;
  }

  if (target.selectedIndex === 0) return;

  node = target;
  do path.push(node.value);
  while (node = node.previousElementSibling);

  if (target.nextElementSibling) {
    const option = path.reduceRight((option, property) => option[property], options);
    draw(target, option);
  } else {
    const option = path.slice(1).reduceRight((option, property) => option[property], options);
    const value = option[target.value];
    if (value == null) return;
    location.href = value.url || value;
  }
}

function draw(target, option) {
  for (const [property, value] of Object.entries(option))
    target.nextElementSibling.add(new Option(property, property));
  target.nextElementSibling.disabled = false;
}

function generateOptions() {
  return {
    "AUDI": {
      "80": {
        "B3": {
          url: "p1.html"
        },
        "B4": {
          url: "p2.html"
        }
      },
      "100": {
        "C3": {
          url: "p3.html"
        },
        "C4": {
          url: "p4.html"
        }
      }
    },
    "BMW": {
      "3 series": {
        "E30": {
          url: "p13.html"
        },
        "E36": {
          url: "p14.html"
        },
        "E46": {
          url: "p15.html"
        }
      },
      "5 series": {
        "E34": {
          url: "p16.html"
        },
        "E39": {
          url: "p17.html"
        },
        "E60": {
          url: "p18.html"
        }
      }
    }		
  };
}

рони 28.06.2022 21:31

VampireFang,
:-?

VampireFang 28.06.2022 21:42

Сможете подсказать?)

рони 28.06.2022 21:43

VampireFang,
могу, но не понимаю, о чём вы просите ... жду переводчика.

VampireFang 28.06.2022 21:59

В общем, тут написан код зависимых списков. При выборе варианта в 3-ем списке открывается страница. Нужно убрать 3-й список и добавить на его место кнопку "Найти", которая будет запускать переход по ссылке при выборе элемента в одном или двух списках

рони 28.06.2022 22:16

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

рони 28.06.2022 22:18

VampireFang,
что должно быть вместо этого и как работать?
<select class="app-select form-control">
  <option selected="">Выберите кузов</option>
  <option value="B3">B3</option>
  <option value="B4">B4</option>
</select>

VampireFang 28.06.2022 22:56

<div class="chained-selects">
  <select class="app-select form-control">
    <option selected>Выберите марку</option>
  </select>                          
  <select class="app-select form-control" disabled>
    <option selected>Выберите модель</option>
  </select>                          
  <button>Найти</button>                                                                  
</div>

Должно выглядеть так
Кнопка должна выполнять переход по ссылке по заданным параметрам в select
Задумка была такая, сделать поиск в каталоге как в примере https://smturbo.by/turbina/

рони 28.06.2022 23:04

VampireFang,
ок ... дознание продолжается)))
что не так?
<!DOCTYPE html>

<html>
<head>
  <title>Untitled</title>
  <meta charset="utf-8">
  <style type="text/css">
  </style>

</head>

<body>
<div class="chained-selects">
  <select class="app-select form-control">
    <option selected>Выберите марку</option>
  </select>
  <select class="app-select form-control" disabled>
    <option selected>Выберите модель</option>
  </select>
  <button>Найти</button>
</div>

<script>
   const options = generateOptions();
const chainedSelects = document.querySelector(".chained-selects");
chainedSelects.addEventListener("change", onChange, false);
draw(chainedSelects.firstChild, options);

function onChange(event) {
  const { target } = event;
  let node = target, path = [];

  while (node = node.nextElementSibling) {
    node.length = 1;
    node.disabled = false;
  }

  if (target.selectedIndex === 0) return;

  node = target;
  do path.push(node.value);
  while (node = node.previousElementSibling);

  if (target.nextElementSibling && target.nextElementSibling.options) {
    const option = path.reduceRight((option, property) => option[property], options);
    draw(target, option);
  } else { return;
    const option = path.slice(1).reduceRight((option, property) => option[property], options);
    const value = option[target.value];
    if (value == null) return;
    location.href = value.url || value;
  }
}

function draw(target, option) {
  for (const [property, value] of Object.entries(option))
    target.nextElementSibling.add(new Option(property, property));
  target.nextElementSibling.disabled = false;
  target.addEventListener('click', function(event) {
	var target = event.target;
});
}

function generateOptions() {
  return {
    "AUDI": {
      "80": {
        "B3": {
          url: "p1.html"
        },
        "B4": {
          url: "p2.html"
        }
      },
      "100": {
        "C3": {
          url: "p3.html"
        },
        "C4": {
          url: "p4.html"
        }
      }
    },
    "BMW": {
      "3 series": {
        "E30": {
          url: "p13.html"
        },
        "E36": {
          url: "p14.html"
        },
        "E46": {
          url: "p15.html"
        }
      },
      "5 series": {
        "E34": {
          url: "p16.html"
        },
        "E39": {
          url: "p17.html"
        },
        "E60": {
          url: "p18.html"
        }
      }
    }
  };
}

</script>
</body>
</html>

VampireFang 29.06.2022 00:29

const options = generateOptions();
const chainedSelects = document.querySelector(".chained-selects");
chainedSelects.addEventListener("change", onChange, false);
draw(chainedSelects.firstChild, options);

function onChange(event) {
  const { target } = event;
  let node = target, path = [];

  while (node = node.nextElementSibling) {
    node.length = 1;
    node.disabled = false;
  }

  if (target.selectedIndex === 0) return;

  node = target;
  do path.push(node.value);
  while (node = node.previousElementSibling);

  if (target.nextElementSibling && target.nextElementSibling.options) {
    const option = path.reduceRight((option, property) => option[property], options);
    draw(target, option);
  } else { return;
    const option = path.slice(1).reduceRight((option, property) => option[property], options);
    const value = option[target.value];
    if (value == null) return;
    location.href = value.url || value;
  }
}

function draw(target, option) {
  for (const [property, value] of Object.entries(option))
    target.nextElementSibling.add(new Option(property, property));
  target.nextElementSibling.disabled = false;
  target.addEventListener('click', function(event) {
	var target = event.target;
});
}

function generateOptions() {
  return {
    "AUDI": {
      "80": {
        url: "p1.html"
      },
      "100": {
        url: "p1.html"
      }
    },
    "BMW": {
      "3 series": {
        url: "p1.html"
      },
      "5 series": {
        url: "p1.html"
      }
    }
  };
}

В общем плане все так. Но вот ещё. Как сделать переход по ссылке при выборе, например, AUDI 80, кликнув на кнопку "найти. Так же если выбрать просто AUDI

рони 29.06.2022 09:45

зависимые селекторы
 
VampireFang,
<!DOCTYPE html>
<html>

<head>
    <title>Untitled</title>
    <meta charset="utf-8">
    <style type="text/css">
    </style>
    <script>
        document.addEventListener("DOMContentLoaded", function() {
            function generateOptions() {
                return {
                    "AUDI": {
                        "80": {
                            url: "p1.html"
                        },
                        "100": {
                            url: "p1.html"
                        }
                    },
                    "BMW": {
                        "3 series": {
                            url: "p1.html"
                        },
                        "5 series": {
                            url: "p1.html"
                        }
                    }
                };
            }
            const elem = document.querySelector(".chained-selects");
            const selects = Array.from(elem.querySelectorAll("select"));
            const getOptions = (obj, path = []) => Object.keys(path.reduce((obj, key) => obj[key], obj));
            const createOptions = (target, options) => target.append(...options.map(i => new Option(i, i)));
            let options = getOptions(generateOptions());
            let target = selects[0];
            createOptions(target, options);
            const change = ({
                target
            }) => {
                let disabled = false,
                    path = [],
                    last;
                for (let select of selects) {
                    let value = select.value;
                    select.disabled = disabled;
                    if (disabled) select.options.length = 1;
                    if (target === select) {
                        last = true;
                    } else if (!disabled && last) {
                        select.options.length = 1;
                        let options = getOptions(generateOptions(), path);
                        createOptions(select, options);
                    };
                    if (select.selectedIndex === 0) disabled = true;
                    else path.push(value);
                }
            }
            elem.addEventListener("change", change);
            elem.querySelector("button").addEventListener("click", () => {
                let obj = generateOptions();
                for (let {value} of selects) {
                    if (value in obj) obj = obj[value];
                    else {
                        value = Object.keys(obj)[0];
                        obj = obj[value];
                    }
                }
                location.href = obj.url
            });
        })
    </script>
</head>

<body>
    <div class="chained-selects">
        <select class="app-select form-control">
    <option selected>Выберите марку</option>
  </select>
        <select class="app-select form-control" disabled>
    <option selected>Выберите модель</option>
  </select>
        <button>Найти</button>
    </div>
</body>

</html>

VampireFang 29.06.2022 18:02

Похоже на то, что я хотел, но вот нюанс. Изменил название ссылки AUDI 100, а переход осуществляется на AUDI 80
"AUDI": {
                   "80": {
                        url: "p1.html"
                        },
                   "100": {
                        url: "audi100.html"
                        }
                    },

рони 29.06.2022 18:10

VampireFang,
исправил, но если выбрано только AUDI -- будет первая ссылка.

VampireFang 29.06.2022 18:15

Спасибо вам огромное!!!) А есть ли возможность сделать для AUDI отдельную ссылку или проще будет первую ссылку подписать "Все модели" и переход будет осуществляться туда сразу при выборе AUDI?

рони 29.06.2022 18:41

Цитата:

Сообщение от VampireFang
А есть ли возможность сделать для AUDI отдельную ссылку

да )))

рони 29.06.2022 19:03

VampireFang,
url пропишите везде, смотрите generateOptions
<!DOCTYPE html>
<html>

<head>
    <title>Untitled</title>
    <meta charset="utf-8">
    <style type="text/css">
    </style>
    <script>
        document.addEventListener("DOMContentLoaded", function() {
            function generateOptions() {
                return {
                    "AUDI": {
                        "80": {
                            url: "p80.html"
                        },
                        "100": {
                            url: "audi100.html"
                        },
                        "url": "AUDI.html"
                    },
                    "BMW": {
                        "3 series": {
                            url: "p3.html"
                        },
                        "5 series": {
                            url: "p5.html"
                        },
                        "url": "BMW.html"
                    },
                    "url": "All.html"
                };
            }
            const elem = document.querySelector(".chained-selects");
            const selects = Array.from(elem.querySelectorAll("select"));
            const getOptions = (obj, path = []) => Object.keys(path.reduce((obj, key) => obj[key], obj)).filter(key => key !== "url");
            const createOptions = (target, options) => target.append(...options.map(i => new Option(i, i)));
            let options = getOptions(generateOptions());
            let target = selects[0];
            createOptions(target, options);
            const change = ({
                target
            }) => {
                let disabled = false,
                    path = [],
                    last;
                for (let select of selects) {
                    let value = select.value;
                    select.disabled = disabled;
                    if (disabled) select.options.length = 1;
                    if (target === select) {
                        last = true;
                    } else if (!disabled && last) {
                        select.options.length = 1;
                        let options = getOptions(generateOptions(), path);
                        createOptions(select, options);
                    };
                    if (select.selectedIndex === 0) disabled = true;
                    else path.push(value);
                }
            }
            elem.addEventListener("change", change);
            elem.querySelector("button").addEventListener("click", () => {
                let obj = generateOptions();
                for (let {
                        value
                    } of selects) {
                    if (value in obj) obj = obj[value];
                    else {
                        if ("url" in obj) break;
                        value = Object.keys(obj)[0];
                        obj = obj[value];
                    }
                }
                location.href = obj.url
            });
        })
    </script>
</head>

<body>
    <div class="chained-selects">
        <select class="app-select form-control">
    <option selected>Выберите марку</option>
  </select>
        <select class="app-select form-control" disabled>
    <option selected>Выберите модель</option>
  </select>
        <button>Найти</button>
    </div>
</body>

</html>

VampireFang 29.06.2022 19:47

Все работает! Благодарствую! Ооочень помогли):) Хорошего вам дня!


Часовой пояс GMT +3, время: 21:54.