在用户选择选项后限制选项(HTML)



到目前为止,对于HTML形式的表单,我有两个选项列表可供选择。然而,在一个列表中选择一个值会使第二个列表中的某些选项变得不可能。具体来说,第一个列表是可能的单位(厘米、英寸、英尺(列表,而第二个列表是位置列表。选择一个单元将限制可能拥有该单元的位置的数量。同样,选择一个国家的价值将限制可用的单位数量。在用户选择地点或单元后,是否有可能以任何方式限制用户的选择?

Unit:
<br>
<select name="unit_input">
<br>
<option selected disabled hidden></option>
<option value="l">League</option>
<option value="m">Mile</option>
<option value="ft">Foot</option>
<option value='m'>Meter</option>
<option value="st">Stage</option>
<option value="km">Kilometer</option>
</select>
<br>
Location:
<br>
<select name="nationality_input">
<br>
<option selected disabled hidden></option>
<option value="italian">Italian</option>
<option value="german">German</option>
<option value="french">French</option>
<option value="hungarian">Hungarian</option>
<option value="british">British</option>
<option value="swiss">Swiss</option>
<option value="spanish">Spanish</option>
</select>
<br>
<br>

是,使用JavaScript:https://codepen.io/dpamonty/pen/PoqRZQd

(不要忘记将ID添加到下拉列表中,以便代码工作(。

<!doctype html>
<html>
<head>
</head>
<body>
Unit:
<br>
<select id="unit_input" name="unit_input" onchange="restrictDropDownLists()">
<br>
<option selected disabled hidden></option>
<option value="l">League</option>
<option value="m">Mile</option>
<option value="ft">Foot</option>
<option value='m'>Meter</option>
<option value="st">Stage</option>
<option value="km">Kilometer</option>
</select>
<br>
<br>
<br>
Location:
<br>
<select id="nationality_input" name="nationality_input" onchange="restrictDropDownLists()">
<br>
<option selected disabled hidden></option>
<option value="italian">Italian</option>
<option value="german">German</option>
<option value="french">French</option>
<option value="hungarian">Hungarian</option>
<option value="british">British</option>
<option value="swiss">Swiss</option>
<option value="spanish">Spanish</option>
</select>
<br>
<br>
<script type="text/javascript">
function restrictDropDownLists(){
var unit = document.getElementById("unit_input");
var nationalilty = document.getElementById("nationality_input");
switch(unit.value){
case "m":
// Options to hide:
nationalilty.options[1].style.display = "none"; // Italian
// etc.
// Options to show:
nationalilty.options[4].style.display = ""; // British
// etc.
break;
// etc.
}
switch(nationalilty.value){
case "british":
// Options to hide:
unit.options[6].style.display = "none"; // Kilometer
// etc.
// Options to show:
unit.options[1].style.display = ""; // League
// etc.
// etc.
}
}
// Restrict on the page load as well:
restrictDropDownLists();
</script>
</body>
</html>

理论上,你应该能够用纯CSS和类似的东西来实现这一点:

#second option { display: none; }
#first:has(> option#a:checked) ~ #second option.a { display: block; }
#first:has(> option#b:checked) ~ #second option.b { display: block; }
#first:has(> option#c:checked) ~ #second option.c { display: block; }
<select id="first">
<option id="a">a</option>
<option id="b">b</option>
<option id="c">c</option>
</select>
<select id="second">
<option class="a b c">Shown for all options</option>
<option class="a">Shown when a selected</option>
<option class="c">Shown when c selected</option>
</select>

但是,目前还没有任何内容支持:has()。通过更改实现,您可以在纯CSS中执行类似的操作。尽管如此,走JavaScript路线要好得多;因为下面有一些注意事项:

label:after { content: ''; display: block; }
input[name=second] { display: none; }
input[name=second] + label { display: none; }
#a:checked ~ input[name=second].a { display: inline; }
#a:checked ~ input[name=second].a + label { display: inline; }
#b:checked ~ input[name=second].b { display: inline; }
#b:checked ~ input[name=second].b + label { display: inline; }
#c:checked ~ input[name=second].c { display: inline; }
#c:checked ~ input[name=second].c + label { display: inline; }
<h4>First</h4>
<input id="a" type="radio" name="first" /><label>A</label>
<input id="b" type="radio" name="first" /><label>B</label>
<input id="c" type="radio" name="first" /><label>C</label>

<h4>Second</h4>
<input id="d" type="radio" name="second" class="a b c" /><label>Shown for all options</label>
<input id="e" type="radio" name="second" class="a" /><label>Shown when a is selected</label>
<input id="f" type="radio" name="second" class="c" /><label>Shown when c is selected</label>

上面的主要问题是,为了依赖~选择器,所有输入都必须是同级输入。因此,这会极大地影响你的布局,以及你实际能实现的目标。一旦支持:has(),纯CSS选项就会存在,但即使这样,您通常也希望获得比CSS所能提供的更多的逻辑处理,即如何允许用户离开并返回表单中的同一点?或者,当所选选项的值消失时会发生什么?这就是JavaScript一定会胜出的地方。

表单是一个完美的例子,说明了基于状态树构建UI(用户界面(是一个好主意。这往往是React或Vue等框架的重点。其中,根据当前的"状态"(描述所选选项的对象树(,UI只是"反应"并隐藏/显示条件元素。从纯粹的"状态"角度来看,将Redux或类似技术作为您正在构建的基础可能是个好主意。

最新更新