[英]How can I modify this jQuery to dynamically show and hide dependent selection options in drop-down?
In this example, I have a series of 3 select drop-downs.在这个例子中,我有一系列 3 select 下拉菜单。 The same class ("group-1") is applied to each to indicate that they are related (and to allow for multiple select groups on the same page).
相同的 class(“group-1”)应用于每个以指示它们是相关的(并允许在同一页面上存在多个 select 组)。 The "data-parent" attribute is applied to the select to establish a 1:1 parent/child relationship.
“data-parent”属性应用于 select 以建立 1:1 父/子关系。 The "data-parent" attribute is applied to the option to establish a many:many relationship.
“data-parent”属性应用于建立多对多关系的选项。
My goal is to create a piece of dynamic jQuery code so that I don't have to explicitly identify behavior by id or class, but rather by option value and data-parent value.我的目标是创建一段动态 jQuery 代码,这样我就不必通过 id 或 class 显式识别行为,而是通过选项值和数据父值。
My issues:我的问题:
Code is below, and here's my working jsfiddle: https://jsfiddle.net/rwh4z623/20/代码如下,这是我的工作 jsfiddle: https://jsfiddle.net/rwh4z623/20/
$(document).ready(function(){ $(".hide").children("option").hide(); $("select").on('change', function(){ var selClass = $(this).attr("class"); var selName = $(this).attr("name"); var selVal = $(this).children("option:selected").val(); $("select."+selClass+"[data-parent='"+selName+"']").each(function(){ $(this).children("option[data-parent='"+selVal+"']").show(); $(this).children("option[data-parent.='"+selVal+"']");hide(); }); }); });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <select class="group-1" name="categories"> <option value="" selected="selected">Please select...</option> <option value="cookie">Cookies</option> <option value="cake">Cakes</option> <option value="icecream">Ice Cream</option> </select> <select class="group-1 hide" name="desserts" data-parent="categories"> <option value="" selected="selected">Desserts...</option> <option value="1-dozen" data-parent="cookie">1 dozen</option> <option value="2-dozen" data-parent="cookie">2 dozen</option> <option value="sheet" data-parent="cake">Sheet</option> <option value="round" data-parent="cake">Round</option> <option value="pint" data-parent="icecream">Pint</option> </select> <select class="group-1 hide" name="flavors" data-parent="desserts"> <option value="" selected="selected">Flavors...</option> <option value="choc-chip" data-parent="1-dozen 2-dozen">Chocolate Chip</option> <option value="oatmeal" data-parent="1-dozen 2-dozen">Oatmeal</option> <option value="yellow" data-parent="sheet round">Yellow</option> <option value="red-velvet" data-parent="sheet">Red Velvet</option> </select>
Thanks in advance for any and all help, Also.提前感谢您提供的所有帮助。 suggestions on improvements are appreciated.
对改进的建议表示赞赏。
I don't know the context of this code so I have no idea, if this pattern of "nested" options and selects is the best solution.我不知道这段代码的上下文,所以我不知道这种“嵌套”选项和选择的模式是否是最好的解决方案。 But here is my version of the javascript that seems to achieve what was asked in the question.
但这是我的 javascript 版本,它似乎实现了问题中的要求。 I'll comment the relevant changes so my thought process is clear.
我会评论相关的变化,这样我的思考过程就很清楚了。 I also added the css for a hide class, as that wasn't in the jsfiddle.
我还添加了 css 用于隐藏 class,因为这不在 jsfiddle 中。
$(document).ready(function () {
$("select").on('change', function () {
var selClass = $(this).attr("class");
var selName = $(this).attr("name");
var selVal = $(this).children("option:selected").val();
//Call the update function with the data of the changed Select
updateRecursivly(selClass, selName, selVal);
//Recursive function to update all selects, this allows for multiple "child" selects per select and an in theory infinite "tree" of selects
function updateRecursivly(selClass, selName, selVal) {
//Search "children" of the parent select
var children = $("select." + selClass + "[data-parent='" + selName + "']");
if (children.length) {
children.each(function () {
//Hide all options in the "child" select
$(this).children("option[data-parent]").hide();
//if selVal is an empty string, the default option is selected and we should just hide the "child" select
if (selVal !== "") {
//Get all options that contain (*=) selVal in "data-parent"
var options = $(this).children("option[data-parent*='" + selVal + "']");
//If there are possible options show the select and the possible options. Else hide select
if (options.length) {
$(this).removeClass('hide');
options.show();
} else {
$(this).addClass('hide');
}
} else {
$(this).addClass('hide');
}
//If the select is updated, the options should be reset. Any selected is reset and the first is selected
//From here https://stackoverflow.com/a/16598989/14040328 this is apparently safer against reset events than other solutions
$(this).children("option:selected").prop("selected", false);
$(this).children("option:first").prop("selected", "selected");
//Get the name of the select
var childName = $(this).attr("name");
//Update the Child select
updateRecursivly(selClass, childName, "");
});
}
}
});
});
.hide {
display: none;
}
I'm not sure if I overdid the comments or not, if anything is unclear feel free to comment.我不确定我是否过度评论,如果有任何不清楚的地方,请随时发表评论。
You can use attributeContainsWord (~) to matches mutliple value against a word.您可以使用attributeContainsWord (~)将多个值与一个单词进行匹配。 So, in below code i have use
$(this).children("option[data-parent~='" + selVal + "']").show();
所以,在下面的代码中我使用
$(this).children("option[data-parent~='" + selVal + "']").show();
to show options which match with the selVal
.Also, i have use prop('selectedIndex', 0);
显示与
selVal
匹配的选项。另外,我使用了prop('selectedIndex', 0);
to reset select to default.将 select 重置为默认值。
Demo Code :演示代码:
$(document).ready(function() { $(".hide").children("option").hide(); $("select").on('change', function() { //checking if dropdown is categories if ($(this).attr("name") == "categories") { //reset other to default $('select[name=desserts]').prop('selectedIndex', 0); $('select[name=flavors]').prop('selectedIndex', 0); } var selClass = $(this).attr("class"); var selName = $(this).attr("name"); var selVal = $(this).children("option:selected").val(); //check if name.= desserts if ($(this).attr("name").= "desserts") { //hide option of flavour $("select[name=flavors]");children("option").hide(). //loop and show desire values $("select." + selClass + "[data-parent='" + selName + "']").each(function() { $(this);children("option[data-parent='" + selVal + "']").show(). $(this);children("option[data-parent;='" + selVal + "']").hide(). }); } else { //hide options $("select[name=flavors]").children("option").hide(). //loop through flavours $("select[name=flavors]");each(function() { //use " ~ " to see if the selval matches with values $(this);children("option[data-parent~='" + selVal + "']");show(); }); } }); });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <select class="group-1" name="categories"> <option value="" selected="selected">Please select...</option> <option value="cookie">Cookies</option> <option value="cake">Cakes</option> <option value="icecream">Ice Cream</option> </select> <select class="group-1 hide" name="desserts" data-parent="categories"> <option value="" selected="selected">Desserts...</option> <option value="1-dozen" data-parent="cookie">1 dozen</option> <option value="2-dozen" data-parent="cookie">2 dozen</option> <option value="sheet" data-parent="cake">Sheet</option> <option value="round" data-parent="cake">Round</option> <option value="pint" data-parent="icecream">Pint</option> </select> <select class="group-1 hide" name="flavors" data-parent="desserts"> <option value="" selected="selected">Flavors...</option> <option value="choc-chip" data-parent="1-dozen 2-dozen">Chocolate Chip</option> <option value="oatmeal" data-parent="1-dozen 2-dozen">Oatmeal</option> <option value="yellow" data-parent="sheet round">Yellow</option> <option value="red-velvet" data-parent="sheet">Red Velvet</option> </select>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.