Последовательный выбор select с поиском
У меня мало опыта и знаний, поставили задачу, нужно срочно сделать. Нужно сделать последовательный выбор: район, потом город/посёлок (Из этого района). Плюс хочу что бы работал поиск, по отдельности получается - но при объёдинении второй select ломается.
toggleSel.addEventListener('change', function() {
if (toggleSel.value == 'р1') {
result.innerHTML = '';
let rusCity = ['---', 'г. 1111111111111111', 'г. 2)', '1', 'с. 3', 'с. 4', 'с. 5'];
for (let i = 0; i < rusCity.length; i++) {
let options = new Option(rusCity[i]);
result.appendChild(options);
}
result.removeAttribute('disabled')
}
if (toggleSel.value == 'р2') {
result.innerHTML = '';
let usCity = ['---', 'г. 1', 'с. 2', 'с. 1', 'с. 3', 'с. 4', 'с. 5', 'с. 6', 'с. 7'];
for (let i = 0; i < usCity.length; i++) {
let options = new Option(usCity[i]);
result.appendChild(options);
}
result.removeAttribute('disabled')
}
if (toggleSel.value == 'р3') {
result.innerHTML = '';
let cnCity = ['---', 'с 12323234', 'с. 2', 'с. 3'];
for (let i = 0; i < cnCity.length; i++) {
let options = new Option(cnCity[i]);
result.appendChild(options);
}
result.removeAttribute('disabled')
}
if (toggleSel.value == '---') {
for (let i = 1; i < result.options.length; i++) {
result.options[i].outerHTML = ''
}
result.setAttribute('disabled', 'disabled')
}
})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>qq3</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">
<link rel="stylesheet" href="./style.css">
</head>
<body>
<h1>Выберите Ваш район</h1>
<select class="sel-group" id="toggleSel">
<option>---</option>
<option>р1</option>
<option>р2</option>
<option>р3</option>
</select>
<h1>Выберите Ваш город/посёлок</h1>
<select class="sel-group" id="result" disabled="disabled">
<option>---</option>
</select>
<script src='https://codepen.io/qwerty_wasd/pen/aKbRrO.js'></script>
<script src="./script.js"></script>
</body>
</html>
Добавляю следующее и , первый select работает, второй ломается, ещё заметил что если заккоментировать то что добавил - перестаёт работать всё равно.. и не в кэше дело, проверял
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/chosen/1.5.1/chosen.min.css">
<script src='https://codepen.io/qwerty_wasd/pen/aKbRrO.js'></script>
<script src="./script.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chosen/1.5.1/chosen.jquery.min.js"></script>
<script type="text/javascript">
$(".sel-group").chosen();
</script>
Посоветуйте, мб по другому как-то лучше сделать, или мб я не заметил что-то. Ещё почему-то, после того как
Ответы (1 шт):
Ничего конкретного про вывод результата и поиск(?) в вопросе не сказано, поэтому пока только оптимизировал код:
const aData = {
р1: ['---', 'г. 1111111111111111', 'г. 2)', '1', 'с. 3', 'с. 4', 'с. 5'],
р2: ['---', 'г. 1', 'с. 2', 'с. 1', 'с. 3', 'с. 4', 'с. 5', 'с. 6', 'с. 7'],
р3: ['---', 'с 12323234', 'с. 2', 'с. 3']
};
toggleSel.addEventListener('change', function() {
result.innerHTML = '';
if (toggleSel.value !== '---') {
aData[toggleSel.value].forEach(el => {
let options = new Option(el);
result.appendChild(options);
});
result.removeAttribute('disabled')
} else {
result.setAttribute('disabled', 'disabled')
}
})
<h1>Выберите Ваш район</h1>
<select class="sel-group" id="toggleSel">
<option>---</option>
<option>р1</option>
<option>р2</option>
<option>р3</option>
</select>
<h1>Выберите Ваш город/посёлок</h1>
<select class="sel-group" id="result" disabled="disabled"></select>
Почти целый плагин для стилизации селекта получился:
const aData = {
р1: ["---", "г. 1111111111111111", "г. 2)", "1", "с. 3", "с. 4", "с. 5"],
р2: ["---", "г. 1", "с. 2", "с. 1", "с. 3", "с. 4", "с. 5", "с. 6", "с. 7"],
р3: ["---", "с 12323234", "с. 2", "с. 3"]
};
toggleSel.addEventListener("change", function() {
result.innerHTML = "";
if (toggleSel.value !== "---") {
aData[toggleSel.value].forEach((el) => result.appendChild(new Option(el)));
result.removeAttribute("disabled");
} else {
result.setAttribute("disabled", "");
}
fCustomSelectUpdate(result);
});
result.addEventListener("change", () => {
// Вывод результата
console.clear(); console.log(`Адрес: ${toggleSel.value} ${result.value}`);
});
/* Закрытие неактивных списков */
function fCustomSelectClose(ev) {
document.querySelectorAll(".sel-container.open").forEach((el) => el.classList.toggle("open", ev.target.closest(".sel-container.open") == el));
}
document.addEventListener("click", fCustomSelectClose);
/* Добавление обёртки */
function fCustomSelectInit(oSelect) {
let width = getComputedStyle(oSelect).width;
oSelect.style.display = "none";
oSelect.insertAdjacentHTML("afterend", `
<div class="sel-container" style=" width: ${width};">
<a class="sel-single">${oSelect.value}</a>
<div class="sel-drop">
<div class="sel-search"><input autocomplete="off"></div>
<ul class="sel-results"></ul>
</div>
</div>
`);
let oSelContainer = oSelect.nextElementSibling;
let oSelSingle = oSelContainer.querySelector(".sel-single");
let oSelSearch = oSelContainer.querySelector(".sel-search");
let oSelSearchInput = oSelSearch.querySelector("input");
let oSelResults = oSelContainer.querySelector(".sel-results");
oSelSingle.addEventListener("click", function() {
oSelContainer.classList.toggle("open");
});
oSelSearchInput.addEventListener("input", function() {
let rExp = new RegExp(`(?:\\s|^)${this.value}`, "gi");
oSelResults.querySelectorAll("li").forEach((el) => el.classList.toggle("active-result", el.textContent.search(rExp) != -1));
});
oSelResults.addEventListener("click", function(ev) {
if (ev.target.tagName != "LI") return false;
oSelSingle.textContent = ev.target.textContent;
oSelect.selectedIndex = ev.target.dataset.index;
oSelect.dispatchEvent(new Event("change"));
oSelContainer.classList.toggle("open");
});
}
document.querySelectorAll(".sel-group").forEach((el) => fCustomSelectInit(el));
/* Обновление пунктов в обёртке */
function fCustomSelectUpdate(oSelect) {
let oSelContainer = oSelect.nextElementSibling;
let oSelResults = oSelContainer.querySelector(".sel-results");
oSelResults.innerHTML = "";
oSelect.querySelectorAll("option").forEach((el, i) => {
oSelResults.insertAdjacentHTML("beforeend", `<li class="active-result" data-index="${i}">${el.textContent}</li>`);
});
oSelect.dispatchEvent(new Event("change"));
oSelContainer.querySelector(".sel-single").textContent = oSelect.value;
}
fCustomSelectUpdate(toggleSel);
body { display: flex; justify-content: center; }
legend { font: bold 14px serif; }
.sel-group { width: 200px; }
.sel-container {
position: relative;
display: inline-block;
vertical-align: middle;
box-sizing: border-box;
font: 13px sans-serif;
user-select: none;
}
.sel-group[disabled]+.sel-container {
filter: contrast(50%) brightness(150%);
pointer-events: none;
}
.sel-single {
position: relative;
display: block;
height: 25px;
padding: 0 25px 0 8px;
overflow: hidden;
border: 1px solid #aaa;
border-radius: 5px;
box-sizing: border-box;
line-height: 25px;
white-space: nowrap;
text-overflow: ellipsis;
text-decoration: none;
color: #444; background-color: #fff;
background-image: linear-gradient( to bottom, #fff 20%, #f6f6f6 50%, #eee 52%, #f4f4f4 100%);
background-clip: padding-box;
box-shadow: 0 0 3px #fff inset, 0 1px 1px rgb(0 0 0 / 10%);
}
.open .sel-single {
border-radius: 5px 5px 0 0;
background-image: linear-gradient( to top, #fff 20%, #f6f6f6 50%, #eee 52%, #f4f4f4 100%);
}
.sel-single::after {
content: "\25BC";
position: absolute;
top: 0; right: 0;
display: block;
height: 25px; width: 20px;
line-height: 25px;
}
.open .sel-single::after { transform: scaley(-1); }
.sel-search {
position: relative;
display: none;
padding: 3px 4px 3px 4px;
box-sizing: border-box;
font-size: 13px;
}
[data-search-input]+.sel-container .sel-search { display: block; }
.sel-search::after {
content: "\1F50D";
position: absolute;
top: 0; right: 0;
display: block;
height: 31px; width: 23px;
line-height: 31px;
color: #aaa;
pointer-events: none;
}
.sel-search input {
height: 25px; width: 100%;
padding: 0px 20px 0px 2px;
box-sizing: border-box;
}
.sel-drop {
position: absolute;
top: 100%; z-index: 1000;
margin-top: -1px;
width: 100%;
border: 1px solid #aaa; border-top: 0;
border-radius: 0 0 4px 4px;
box-sizing: border-box;
background: #fff;
background-clip: padding-box;
box-shadow: 0 4px 5px rgb(0 0 0 / 15%);
clip: rect(0, 0, 0, 0);
-webkit-clip-path: inset(100% 100%);
clip-path: inset(100% 100%);
}
.open .sel-drop {
clip: auto;
-webkit-clip-path: none;
clip-path: none;
}
.sel-results {
position: relative;
margin: 0 4px 4px 0;
max-height: 240px;
padding: 0 0 0 4px;
box-sizing: border-box;
overflow: hidden auto;
color: #444;
}
.sel-results li {
margin: 0;
display: none;
padding: 5px 6px;
list-style: none;
line-height: 15px;
word-wrap: break-word;
}
.sel-results li.active-result {
display: list-item;
cursor: pointer;
}
.sel-results li:hover {
color: #fff;
background-image: linear-gradient(to bottom, #53b2fc, #1385e5);
}
<fieldset>
<legend>Выберите Ваш район</legend>
<!-- Чтобы появилось поле поиска, добавьте атрибут "data-search-input" -->
<select class="sel-group" id="toggleSel">
<option>---</option>
<option>р1</option>
<option>р2</option>
<option>р3</option>
</select>
</fieldset>
<fieldset>
<legend>Выберите Ваш город/посёлок</legend>
<select class="sel-group" id="result" data-search-input disabled></select>
</fieldset>