[HELP] Зависимые списки Select с переходом по URL на JS
Элите программирования привет! Есть такой скрипт каскада выпадающих меню: https://codepen.io/mgiulio/pen/OMwPJa
Как я понимаю в каждый <select> генерируется тег <option> из массива формата JSON (наверное), который расположен в конце скрипта. Вопрос: Есть 3 выпадающих меню. Как сделать так, чтоб выбирая из 3 меню какой-либо элемент, был переход по URL (каждому пункту привязан свой URL)? Я понимаю, что нужно третьему <select> задать onChange. URL будет браться из атрибута value: <option value="https://">Пункт №1</option> Но как задать свой атрибут value каждому тегу <option>, которые генерируется из массива? |
Для третьего селекта прикрутил:
onchange="if (this.value) window.location.href = this.value" и в коде дописал фрагмент, чтобы при создании <option> добавлялся атрибут value var urls = document.querySelectorAll('#select-3 > option:not(:first-child'); for (j = 0; j < urls.length; ++j) { urls[j].setAttribute('value', ' '); } Вопрос: как теперь value для каждого option из массива (см. конец скрипта) задать также массивом? <div class="chained-selects"> <select id="select-1"> <option selected>Choose level 1 option</option> <option>1</option> <option>2</option> <option>3</option> </select> <select id="select-2" disabled> <option selected>Choose level 2 option</option> </select> <select id="select-3" onchange="if (this.value) window.location.href = this.value" disabled > <option selected>Choose level 3 option</option> </select> </div> var options = generateOptions(); document.querySelector('.chained-selects').addEventListener('change', onChange, false); function onChange(e) { e.stopPropagation(); var s = e.target; if (!s.nextElementSibling) return; var next = s.nextElementSibling; if (s.selectedIndex === 0) deactivateBoxes(next); else { var path = []; for (var p = s; p; p = p.previousElementSibling) { var selOptNode = p.options[p.selectedIndex]; path.push(selOptNode.value); } path.reverse(); var children = path.reduce( function(o, optName) { return o[optName]; }, options ); children = Object.keys(children); // Insert children in s.nextChild for (var q = next.firstElementChild.nextElementSibling; q; q = nextq) { nextq = q.nextElementSibling; next.removeChild(q); } for (var i = 0; i < children.length; ++i) { var optEl = document.createElement('option'); optEl.innerHTML = children[i]; next.appendChild(optEl); /**/ var urls = document.querySelectorAll('#select-3 > option:not(:first-child'); for (j = 0; j < urls.length; ++j) { urls[j].setAttribute('value', ' '); } /**/ } next.selectedIndex = 0; next.disabled = false; deactivateBoxes(next.nextElementSibling); } } function deactivateBoxes(s) { while (s) { s.selectedIndex = 0; s.disabled = true; s = s.nextElementSibling; } } function generateOptions() { return { '1': { '1-1': { '1-1-1': null, '1-1-2': null }, '1-2': { '1-2-1': null, '1-2-2': null, '1-2-3': null, '1-2-4': null, }, '1-3': { '1-3-1': null, '1-3-2': null, '1-3-3': null, '1-3-4': null, '1-3-5': null, } }, '2': { '2-1': { '2-1-1': null, '2-1-2': null }, '2-2': { '2-2-1': null, '2-2-2': null, '2-2-3': null, '2-2-4': null, }, '2-3': { '2-3-1': null, '2-3-2': null, '2-3-3': null, '2-3-4': null, '2-3-5': null, } }, '3': { '3-1': { '3-1-1': null, '3-1-2': null }, '3-2': { '3-2-1': null, '3-2-2': null, '3-2-3': null, '3-2-4': null, }, '3-3': { '3-3-1': null, '3-3-2': null, '3-3-3': null, '3-3-4': null, '3-3-5': null, } } }; } |
зависимые селекты
Esm1nec,
выбирать для теста 1 , 1 - 1, ... <!DOCTYPE html> <html> <head> <title>Untitled</title> <meta charset="utf-8"> </head> <body> <div class="chained-selects"> <select id="select-1"> <option selected>Choose level 1 option</option> <option>1</option> <option>2</option> <option>3</option> </select> <select id="select-2" disabled> <option selected>Choose level 2 option</option> </select> <select id="select-3" disabled> <option selected>Choose level 3 option</option> </select> </div> <script> var options = generateOptions(); document.querySelector('.chained-selects').addEventListener('change', onChange, false); function onChange(e) { e.stopPropagation(); var s = e.target; if (!s.nextElementSibling) return; var next = s.nextElementSibling; if (s.selectedIndex === 0) deactivateBoxes(next); else { var path = []; for (var p = s; p; p = p.previousElementSibling) { var selOptNode = p.options[p.selectedIndex]; path.push(selOptNode.value); } path.reverse(); var children = path.reduce( function(o, optName) { return o[optName]; }, options ); /* if (children === null) { children = fetch(path); o[...] = children; } */ var values = next.id == "select-3" ? Object.values(children) : []; children = Object.keys(children); // Insert children in s.nextChild for (var q = next.firstElementChild.nextElementSibling; q; q = nextq) { nextq = q.nextElementSibling; next.removeChild(q); } for (var i = 0; i < children.length; ++i) { var text = children[i]; var value = values[i] || text; var optEl = new Option(text, value) next.appendChild(optEl); } next.selectedIndex = 0; next.disabled = false; deactivateBoxes(next.nextElementSibling); } } function deactivateBoxes(s) { while (s) { s.selectedIndex = 0; s.disabled = true; s = s.nextElementSibling; } } function generateOptions() { return { '1': { '1-1': { '1-1-1 codepen': 'https://codepen.io/', '1-1-2 google': 'https://www.google.com/' }, '1-2': { '1-2-1': null, '1-2-2': null, '1-2-3': null, '1-2-4': null, }, '1-3': { '1-3-1': null, '1-3-2': null, '1-3-3': null, '1-3-4': null, '1-3-5': null, } }, '2': { '2-1': { '2-1-1': null, '2-1-2': null }, '2-2': { '2-2-1': null, '2-2-2': null, '2-2-3': null, '2-2-4': null, }, '2-3': { '2-3-1': null, '2-3-2': null, '2-3-3': null, '2-3-4': null, '2-3-5': null, } }, '3': { '3-1': { '3-1-1': null, '3-1-2': null }, '3-2': { '3-2-1': null, '3-2-2': null, '3-2-3': null, '3-2-4': null, }, '3-3': { '3-3-1': null, '3-3-2': null, '3-3-3': null, '3-3-4': null, '3-3-5': null, } } }; } document.querySelector("#select-3").addEventListener("change", function() { if(this.value.startsWith("https") ) window.location = this.value; }) </script> </body> </html> |
Снимаю шляпу!
Мне тут ещё друг помог, делюсь другим для помощи! :dance: var options = generateOptions(); document .querySelector(".chained-selects") .addEventListener("change", onChange, false); function onChange(e) { e.stopPropagation(); var s = e.target; if (!s.nextElementSibling) return; var next = s.nextElementSibling; if (s.selectedIndex === 0) deactivateBoxes(next); else { var path = []; for (var p = s; p; p = p.previousElementSibling) { var selOptNode = p.options[p.selectedIndex]; path.push(selOptNode.value); } path.reverse(); var children = path.reduce(function(o, optName) { return o[optName]; }, options); let childrenNames = []; for (let key in children) { let obj = { name: key, params: children[key] }; childrenNames.push(obj); } // Insert childrenNames in s.nextChild for (let q = next.firstElementChild.nextElementSibling; q; q = nextq) { nextq = q.nextElementSibling; next.removeChild(q); } for (let i = 0; i < childrenNames.length; ++i) { let optEl = document.createElement("option"); let current = childrenNames[i]; let { name, params } = current; optEl.innerHTML = name; if (params && params.url) { optEl.setAttribute('url', params.url); } next.appendChild(optEl); } next.selectedIndex = 0; next.disabled = false; deactivateBoxes(next.nextElementSibling); } } function deactivateBoxes(s) { while (s) { s.selectedIndex = 0; s.disabled = true; s = s.nextElementSibling; } } function generateOptions() { return { audi: { "audi model 1": { "audi model 1 url 1": { url: "https://google.com" }, "audi model 1 url 2": { url: "https://yandex.ru" } }, "audi model 2": { "1-2-1": null, "1-2-2": null, "1-2-3": null, "1-2-4": null }, "audi model 3": { "1-3-1": null, "1-3-2": null, "1-3-3": null, "1-3-4": null, "1-3-5": null } }, "2": { "2-1": { "2-1-1": null, "2-1-2": null }, "2-2": { "2-2-1": null, "2-2-2": null, "2-2-3": null, "2-2-4": null }, "2-3": { "2-3-1": null, "2-3-2": null, "2-3-3": null, "2-3-4": null, "2-3-5": null } }, "3": { "3-1": { "3-1-1": null, "3-1-2": null }, "3-2": { "3-2-1": null, "3-2-2": null, "3-2-3": null, "3-2-4": null }, "3-3": { "3-3-1": null, "3-3-2": null, "3-3-3": null, "3-3-4": null, "3-3-5": null } } }; } var urlDropdownRef = document.querySelector("#select-3"); urlDropdownRef.addEventListener("change", onUrlDropdownChange); function onUrlDropdownChange(e) { e.stopPropagation(); let { target } = e; let { options, selectedIndex } = target; let selectedElem = options[selectedIndex]; let url = selectedElem.getAttribute('url'); if (url) { redirect(url); } } function redirect(url) { window.location.assign(url); } |
Esm1nec, ещё способ...
<div class="chained-selects"> <select id="select-1"> <option selected>Choose level 1 option</option> </select> <select id="select-2" disabled> <option selected>Choose level 2 option</option> </select> <select id="select-3" disabled> <option selected>Choose level 3 option</option> </select> </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 = 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: { "audi model 1": { "audi model 1 url 1": { url: "https://google.com" }, "audi model 1 url 2": { url: "https://yandex.ru" } } }, "1": { "1-1": { "1-1-1": null }, "1-2": { "1-2-1": null }, "1-3": { "1-3-1": null, "1-3-2": null } } }; } </script> |
Подскажите пожалуйста, я новичок, а как сделать чтобы ссылка открывалась в новой вкладке, куда нужно подставить window.open?
|
Что бы ссылка открывалась
<a href="...url..." target="_blank">ссылка</a> |
Цитата:
|
Вроде получилось)
заменил это document.querySelector("#select-3").addEventListener("change", function() { if(this.value.startsWith("https") ) window.location = this.value; }) на это document.querySelector("#select-3").addEventListener("change", function() { if(this.value.startsWith("https")) window.open(this.value); }) |
Часовой пояс GMT +3, время: 13:14. |