简体   繁体   中英

What is the closest solution to this Idea/Problem I have with forms in HTML?

I want to make a select form in HTML that checks that displays a secondary select group if certain options in the first select group are selected

<body>
    <form name="Test">
        <!-- all the factors to account for when calculating odds-->
        <div>
            <label>
            <select name="FirstList" id="FirstListID">
                <option value="1">First option</option>
                <option value="2">Second option</option>
                <option value="3">Third option</option>
            </select><br>
                
            <!-- SecondList would be visible if "1" is selected-->
            <label name="SecondList" style="display:none">List for "1":
                <select name="SecondListSelect" id="SecondListSelectID">
                    <option value="3">Placeholder</option>
                </select><br>
            </label>
            <!-- ThirdList would be visible if "2" is selected-->
            <label name="ThirdList" style="display:none">List for "2":
                <select name="ThirdListSelect" id="ThirdListSelectID">
                    <option value="4">Placeholder</option>
                </select><br>
            </label>
            <!-- No secondary select form appears if "3" is selected-->
        </div>
    </form>
</body>

I've tried using AddEventListeners but the code doesn't appear that maintainable since I plan on adding more options in the primary drop down menu so I would need to constantly add what secondary select groups appear based on what primary option is selected. How could I go about coding this in JS?

Give each <label> an identifier tying it to the value for which it should be visible. A data attribute would work. Then, whenever the <select> changes, iterate over all such labels and hide them. Take the .value from the select and use string concatenation to construct a selector for the element with that in the dataset, and then you can select that element and show it.

For example, with labels like

<label data-option=1>

you could have

for (const label of document.querySelectorAll('[data-option]')) {
  label.style.display = 'none';
}
document.querySelector(`[data-option=${select.value}]`).style.display = 'block';

inside the change listener.

Store the options of the second <select> element in an object. Make sure the keys match the value attribute value of the options in the first <select> .

Listen for a change event on the first <select> . Whenever a change happens, empty the options of the second <select> , get the new options from the object and create new <option> elements with that data.

Now you have a dynamic <select> element that is easy to scale.

 const optionData = { '1': [ { label: 'Foo', value: 'foo', } ], '2': [ { label: 'Bar', value: 'bar', }, { label: 'Baz', value: 'baz', } ], '3': [ { label: 'Hello', value: 'hello', }, { label: 'World', value: 'world', } ] }; const firstList = document.querySelector('#first-list'); const secondList = document.querySelector('#second-list'); function removeOptions(selectElement) { for (let i = selectElement.options.length - 1; i >= 0; i--) { selectElement.remove(i); } } // Update the second `<select>` based on the first's selection. firstList.addEventListener('change', event => { const value = event.target.value; const options = optionData[value]; removeOptions(secondList); for (const { label, value } of options) { const option = new Option(label, value); secondList.add(option); } });
 <label for="first-list">List One</label> <select name="first-list" id="first-list"> <option value="" selected disabled>Make a selection</option> <option value="1">First option</option> <option value="2">Second option</option> <option value="3">Third option</option> </select> <label for="second-list">List Two</label> <select name="second-list" id="second-list"> <option value="" selected disabled>No options yet</option> </select>

You could build the selectors from your js file:

 const optionGroups = { "first": [ { "text": "for first - 1", "value": 1 } ], "second": [ { "text": "for second - 1", "value": 1 }, { "text": "for second - 2", "value": 2 } ], "third": [ { "text": "for third - 1", "value": 1 }, { "text": "for third - 2", "value": 2 }, { "text": "for third - 3", "value": 3 } ] }, mainSelect = document.querySelector('#mainSelect'), secondarySelect = document.querySelector('#secondarySelect'); async function startWithMainSelect() { for (let key of Object.keys(optionGroups)) { const option = new Option(key); mainSelect.appendChild(option); } onChangeMainSelect(); } function onChangeMainSelect() { while (secondarySelect.firstChild) secondarySelect.firstChild.remove(); for (let _option of optionGroups[mainSelect.value]) { const option = new Option(_option.text, _option.value); secondarySelect.appendChild(option); } } mainSelect.addEventListener('change', onChangeMainSelect); startWithMainSelect();
 <.DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width"> <title>replit</title> <link href="style:css" rel="stylesheet" type="text/css" /> </head> <body> <h4>Main:</h4> <select id="mainSelect"></select> <br> <h4>Secondary:</h4> <select id="secondarySelect"></select> <script src="https.//replit.com/public/js/replit-badge.js" theme="blue" defer></script> <script src="script.js"></script> </body> </html>

If there were a lot of options, you could move them into a json file and request them from there. Here's an example .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM