javascript - 如何修改此 jQuery 以在下拉列表中动态显示和隐藏相关选择选项?

标签 javascript html jquery select option

在这个例子中,我有一系列 3 个选择下拉菜单。相同的类(“group-1”)应用于每个类以指示它们是相关的(并允许在同一页面上选择多个组)。 “data-parent”属性应用于选择以建立1:1的父/子关系。 “data-parent”属性应用于建立多:多关系的选项。
我的目标是创建一段动态 jQuery 代码,这样我就不必通过 id 或类明确识别行为,而是通过选项值和数据父值。
我的问题:

  • 第三个下拉菜单根本不更新。我认为其中一些可能有多个数据父值(用空格分隔),但即使我将它们更改为只有一个,它仍然不会随着第二个下拉列表的更改而更新.
  • 我不确定如何在第三个下拉列表的选项中实现“许多”数据父值。拆分字符串,创建一个数组,并检查该值是否在数组中?
  • 如何通过更改父下拉列表将第二个和第三个下拉列表重置为“默认”值?例如,如果我从第一个中选择“Cookies”,则第二个中会显示“1 打”和“2 打”。但是,如果我选择“1 打”,然后将第一个框更改为“蛋糕”,则即使“表”和“圆形”是下拉列表中唯一可用的选项,“1 打”仍然处于选中状态。我希望它重置为默认值(“甜点...”)。

  • 代码在下面,这是我的工作 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>

    在此先感谢您的任何帮助!此外,对改进的建议表示赞赏。

    最佳答案

    我不知道这段代码的上下文,所以我不知道这种“嵌套”选项和选择的模式是否是最好的解决方案。但这是我的 javascript 版本,它似乎实现了问题中的要求。我会评论相关的变化,所以我的思考过程很清楚。我还为隐藏类添加了 css,因为它不在 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;
    }
    
    我不确定我的评论是否过度,如果有任何不清楚的地方,请随时发表评论。

    关于javascript - 如何修改此 jQuery 以在下拉列表中动态显示和隐藏相关选择选项?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63264629/

    相关文章:

    javascript - 如何使用 wp_localize_script 更改 JavaScript 项目数组

    javascript - 用 JavaScript 解析表情

    javascript - Fancybox 不从外部 URL 加载图像

    css - 将 Div 堆叠在其他标题元素之上

    JavaScript:getElementById 在 IE8 中不起作用

    javascript - 通过更改左侧绝对位置的 JQuery slider

    javascript - 从 DIV 中删除元素以及之前插入的值

    javascript - 如何通过 Chrome 扩展突出显示 PDF 文件中的文本

    php - 如果用户在填写第一个选项卡的数据之前单击第二个选项卡,如何显示错误消息

    javascript - 如何清除谷歌地图中的现有标记?