18.01.2020, 13:28
|
|
Новичок на форуме
|
|
Регистрация: 18.03.2018
Сообщений: 8
|
|
[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>, которые генерируется из массива?
|
|
18.01.2020, 14:05
|
|
Новичок на форуме
|
|
Регистрация: 18.03.2018
Сообщений: 8
|
|
Для третьего селекта прикрутил:
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, 18.01.2020 в 14:11.
|
|
18.01.2020, 15:29
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,109
|
|
зависимые селекты
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>
|
|
18.01.2020, 18:36
|
|
Новичок на форуме
|
|
Регистрация: 18.03.2018
Сообщений: 8
|
|
Снимаю шляпу!
Мне тут ещё друг помог, делюсь другим для помощи!
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);
}
|
|
19.01.2020, 10:17
|
|
Профессор
|
|
Регистрация: 20.12.2009
Сообщений: 1,714
|
|
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>
Последний раз редактировалось Malleys, 19.01.2020 в 10:19.
|
|
20.10.2023, 14:15
|
Новичок на форуме
|
|
Регистрация: 20.10.2023
Сообщений: 3
|
|
Подскажите пожалуйста, я новичок, а как сделать чтобы ссылка открывалась в новой вкладке, куда нужно подставить window.open?
|
|
20.10.2023, 14:42
|
|
Профессор
|
|
Регистрация: 03.02.2020
Сообщений: 2,745
|
|
Что бы ссылка открывалась
<a href="...url..." target="_blank">ссылка</a>
|
|
20.10.2023, 15:07
|
Новичок на форуме
|
|
Регистрация: 20.10.2023
Сообщений: 3
|
|
Сообщение от рони
|
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>
|
Простите, я не правильно выразился, меня интересует как в этом готовом решении нужно правильно подправить, чтобы ссылка после выбора из выпадающего списка открывалась в новой вкладке?
|
|
20.10.2023, 16:34
|
Новичок на форуме
|
|
Регистрация: 20.10.2023
Сообщений: 3
|
|
Вроде получилось)
заменил это
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);
})
|
|
|
|