根据另一个选择中选择的值过滤选择(下拉)选项

问题描述 投票:0回答:3

我下面的代码使用结果数组中的值填充选择。 - 我想要做的是创建一个额外的选择,它将根据所选的值 {tag} 过滤结果。

例如:

我希望第一个选择仅将标签作为选项,根据所选标签,第二个选择将仅显示按所选标签过滤的名称。

我也愿意接受关于更好方法的意见,例如,如果无线电选项更适合过滤器,那么我会使用它们。 - 预先感谢!

更新:代码片段已更改为包含带有标签值的附加选择。只需要弄清楚如何根据第一次选择中选择的标签进行第二次选择更改。

let result = [
  {name: "some name", tag: "some tag"},
  {name: "some name1", tag: "some tag1"},
  {name: "some name2", tag: "some tag2"},
  {name: "some name2-2", tag: "some tag2"}
];

let hcList = document.getElementById("hclist");
Object.keys(result).map((key) => hcList.add(new Option(result[key].name, JSON.stringify(result[key]))));

    let uniqueTags = [...new Set(result.map((item) => item.tag))];

    let tagList = document.getElementById("taglist");
    Object.keys(uniqueTags).map((key) =>
      tagList.add(new Option(uniqueTags[key]))
    );
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
</head>
<body>
<select id="taglist"></select>
  <select id="hclist"></select>
</body>
</html>

javascript api filter drop-down-menu
3个回答
1
投票

看这个。我在必要的地方添加了评论:

let result = [
  {name: "some name", tag: "some tag"},
  {name: "some name1", tag: "some tag1"},
  {name: "some name2", tag: "some tag2"},
  {name: "some name2-2", tag: "some tag2"}
];

//Generic function to fill a dropdown with options 
let populateDropDown = (params) => {
    params.optionsToPopulate.forEach(item => {
        params.ddlElement.add(new Option(item[`${params.text}`], item[`${params.text}`]))
    })
}

//Initialize tags dropdown
(function(){
  document.getElementById("tagsDdl").addEventListener('change', (event) => {
    tagChanged(event);
  });

    let params = {
        optionsToPopulate:result,
        ddlElement:document.getElementById("tagsDdl"),
        id:"tag",
        text:"tag"
    }
    populateDropDown(params);

    //Uncomment the below code if you want to set names dropdown on page load based on the value of tags dropdown on pageload
    /*  let paramsNames = {
            optionsToPopulate:result.filter(item => item.tag === document.getElementById("tagsDdl").value),
            ddlElement:document.getElementById("namesDdl"),
            id:"name",
            text:"name"
        }
        populateDropDown(paramsNames);*/

})();

//Tags dropdown change event.
let tagChanged = (event) => {   
    let tagDdlValue = event.target.value;

    //filter the results based on the value of tags dropdonw
    let optionsToAdd = result.filter(item => item.tag === tagDdlValue);
    let namesDdl = document.getElementById("namesDdl");
    namesDdl.options.length=0;
    let params = {
        optionsToPopulate:optionsToAdd,
        ddlElement:namesDdl,
        id:"name",
        text:"name"
    }   
    populateDropDown(params);
}
<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>
  Tags DDL: <select id="tagsDdl"></select> 

  <br><br><br>
  Names DDL: <select id="namesDdl"></select>
</body>
</html>


0
投票

你可以使用JQuery轻松实现这一点。使用 $element.change() - 每次更改第一个 select.selectedValue -> 你可以刷新并更新第二个 select。

 $('#hclist').change(function(){
       refreshSecondSelect($(this).val());
    });

参见示例:示例


0
投票

HTML 选择关系 - 简单 JS 库 - 100%

Html 选择彼此相关的标签。您可以根据其他选择标签值过滤选择选项。

您可以从这里获取完整的库:https://github.com/deirvlon/select-relations

/*
--------------------------------------------------
@ Select Relations JS @
Version: 1.1.2

Author: Kamran Gasimov
Created: 09.04.2024
Updated: 23.04.2024
© All rights are reserved Deirvlon Technologies.
--------------------------------------------------
*/

function SelectRelations() {
    document.addEventListener('DOMContentLoaded', function () {

        const selectRelations = document.querySelectorAll('.select-relations');

        selectRelations.forEach(select => {
            // Check if Select2 is initialized
            const isSelect2Initialized = $(select).hasClass('select2') !== undefined;

            // Add event listener for change event
            select.addEventListener('change', function () {
                updateFiltering(this);
            });

            // If Select2 is initialized, also listen to its change event
            if (isSelect2Initialized) {
                $(select).on('change.select2', function () {
                    updateFiltering(this);
                });
            }

        });

        initializeFiltering();

    });

    function initializeFiltering() {
        const selectRelations = document.querySelectorAll('.select-relations');

        selectRelations.forEach(select => {
            updateFiltering(select, false);
        });

        // Reset parent selects' selected options if they are hidden due to filtering
        resetParentSelects();
    }

    function updateFiltering(select, restart = true) {
        const selectedOption = select.options[select.selectedIndex];
        const parentId = select.getAttribute('id');
        const parentValues = parentId.split(',').map(parentId => document.getElementById(parentId).value).join(',');

        document.querySelectorAll(`[data-sf-parent*="${parentId}"]`).forEach(childSelect => {

            if (childSelect.tagName == "SELECT")
                // SELECT INPUT
                childSelect.querySelectorAll('option').forEach(option => {
                    const relationData = option.getAttribute('data-pr');
                    if (relationData) {
                        const displayOption = relationData.split('&').some(pair => {
                            const [selectId, selectValues] = pair.split(':');

                            var el_parent = document.getElementById(selectId);
                            var ids = selectValues.split(',');
                            return ids.includes(el_parent.value) || (el_parent.options[el_parent.selectedIndex]!=undefined && ids.includes(el_parent.options[el_parent.selectedIndex].dataset.alt));
                        });
                        option.disabled = displayOption ? false : true;
                        option.hidden = displayOption ? false : true;
                        option.ariaHidden = displayOption ? false : true;
                    }
                });
            else {
                //NORMAL INPUTS
                const relationData = childSelect.getAttribute('data-pr');
                if (relationData) {
                    const displayOption = relationData.split('&').some(pair => {
                        const [selectId, selectValues] = pair.split(':');

                        var el_parent = document.getElementById(selectId);
                        var ids = selectValues.split(',');
                        return ids.includes(el_parent.value) || (el_parent.options[el_parent.selectedIndex]!=undefined && ids.includes(el_parent.options[el_parent.selectedIndex].dataset.alt));
                    });
                    childSelect.style.display = (displayOption) ? '' : 'none';
                }
            }
        });


        // Reset parent selects' selected options if they are hidden due to filtering
        if (restart)
            resetParentSelects();
    }

    function resetParentSelects() {
        document.querySelectorAll(`[data-sf-parent]`).forEach(childSelect => {

            if (childSelect.tagName == "SELECT") {
                // SELECT INPUT

                if (childSelect.selectedIndex == null || childSelect.selectedIndex == -1)
                    return;

                let selectOption = childSelect.options[childSelect.selectedIndex];
                if (selectOption.disabled) {
                    $(childSelect).val(null).trigger('change.select2');
                }
            }



        });
    }

}

// autorun
SelectRelations(); //Init
<div class="container">
  <select id="countrySelect" class="select-relations">
    <option value="USA">USA</option>
    <option value="Canada">Canada</option>
  </select>
  <select id="citySelect" class="select-relations" data-sf-parent="countrySelect">
    <option value="New York" data-pr="countrySelect:USA">New York</option>
    <option value="Los Angeles" data-pr="countrySelect:USA">Los Angeles</option>
    <option value="Toronto" data-pr="countrySelect:Canada">Toronto</option>
    <option value="Vancouver" data-pr="countrySelect:Canada">Vancouver</option>
  </select>
  <select id="regionSelect" class="select-relations" data-sf-parent="citySelect">
    <option value="Manhattan" data-pr="citySelect:New York">Manhattan</option>
    <option value="Brooklyn" data-pr="citySelect:New York">Brooklyn</option>
    <option value="Hollywood" data-pr="citySelect:Los Angeles">Hollywood</option>
    <option value="Downtown" data-pr="citySelect:Los Angeles,citySelect:Toronto">Downtown</option>
    <option value="North Vancouver" data-pr="citySelect:Vancouver">North Vancouver</option>
    <option value="West Vancouver" data-pr="citySelect:Vancouver">West Vancouver</option>
  </select>
</div>


<!-- Select Relations JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="select-relations.js"></script>

© www.soinside.com 2019 - 2024. All rights reserved.