Forum Moderators: open

Message Too Old, No Replies

multiple dropdown group selection

How to populate a second dropdown depending on first dropdown but with mult

         

Wayder

11:16 pm on Aug 10, 2023 (gmt 0)

10+ Year Member Top Contributors Of The Month



I have the following code to populate a second dropdown depending on first dropdown selection. Does anyone know how I should convert this for multiple groups of dropdowns?

Thank you


<script>
var widthObject = {
"10": ["Emerald", "Black"],
"20": ["Purple", "Gold", "Green"],
}

function changeColour() {
document.getElementById("colour-list").options.length = 0;

var colourListArray = widthObject[document.getElementById("width-list").value];
console.log(document.getElementById("colour-list").options);

for (var item = 0; item < colourListArray.length; item++) {
document.getElementById("colour-list").options[document.getElementById("colour-list").options.length] = new Option(colourListArray[item], colourListArray[item]);
}
}
</script>

<div>
<select id="width-list" onchange="changeColour()">
<option value="none" disabled selected>width</option>
<option value="10">10</option>
<option value="20">20</option>
</select>
<select id="colour-list">
<option value="none" disabled selected>colour</option>
</select>
</div>
// add second (or more) dropdown group(s)
<div>
<select id="width-list" onchange="changeColour()">
<option value="none" disabled selected>width</option>
<option value="10">10</option>
<option value="20">20</option>
</select>
<select id="colour-list">
<option value="none" disabled selected>colour</option>
</select>
</div>

csdude55

5:30 am on Aug 22, 2023 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



The immediate problem that I see is that you have the same ID twice, so the script doesn't know which one is which. Try changing the second ones to something like:

<div>
<select id="width-list-two" onchange="changeColour()">
<option value="none" disabled selected>width</option>
<option value="10">10</option>
<option value="20">20</option>
</select>
<select id="colour-list-two">
<option value="none" disabled selected>colour</option>
</select>
</div>


That'll fix the first issue, but then of course you'll need to set up arrays or something to get the same thing to work with the second list (since it has a different name).

csdude55

5:33 pm on Aug 22, 2023 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I know it's several days since you asked and this is probably irrelevant, but I was stressed with my own work so I played with yours as a mental break :-)

I changed the IDs to a class so that they could be duplicated, then gave a unique identifier using data-attributes. The first list is data-width=1 and data-color=1, the second list is data-width=2 and data-color=2, and so on. Then I modified the script to use a variable that points back to those data values; eg, changeColour(1), changeColour(2), etc.

I also used a variable to shorten the document.querySelector to save space and bandwidth, and use for/of instead of an iterator to also save space and bandwidth. That's just my own style, though, if you find the other way easier to read then I don't think it really matters.

[jsfiddle.net...]

<div>
<select class="width-list" data-width=1 onchange="changeColour(1)">
<option value="none" disabled selected>width</option>
<option value="10">10</option>
<option value="20">20</option>
</select>
<select class="colour-list" data-color=1>
<option value="none" disabled selected>colour</option>
</select>
</div>
// add second (or more) dropdown group(s)
<div>
<select class="width-list" data-width=2 onchange="changeColour(2)">
<option value="none" disabled selected>width</option>
<option value="10">10</option>
<option value="20">20</option>
</select>
<select class="colour-list" data-color=2>
<option value="none" disabled selected>colour</option>
</select>
</div>

<script>
var widthObject = {
"10": ["Emerald", "Black"],
"20": ["Purple", "Gold", "Green"],
}

function changeColour(id) {
var w = document.querySelector('[data-width="' + id + '"]'),
l = document.querySelector('[data-color="' + id + '"]');

l.options.length = 0;

var colourListArray = widthObject[w.value];

for (var item of colourListArray) {
l.options[l.options.length] = new Option(item, item);
}
}
</script>

Wayder

7:46 pm on Aug 22, 2023 (gmt 0)

10+ Year Member Top Contributors Of The Month



The ID's were an issue and I did change that. In the end, after much research and headache I ended up with the following where the width and length are selected by type and the colour is selected by width.

I hope this helps someone.


<script>
var ribbonWidths = ["10", "15", "25", "38", "100"];
var foilWidths = ["30", "55", "105"];
var ribbonLengths = ["25", "100"];
var foilLengths = ["200"];
var receiveColourList10 = ["Black","White"];
var receiveColourList15 = ["Black","White"];
var receiveColourList25 = ["Gold","Black","Dark Purple","Hunter Green","White"];
var receiveColourList38 = ["Black","White"];
var receiveColourList100 = [""];
var receiveColourList30 = ["Aubergine","Black","Green","Metallic","White"];
var receiveColourList55 = ["Black","Metallic","Blue","White"];
var receiveColourList105 = ["Black","White"];

function changeReceiveType(selectElement) {
var widthSelect = selectElement.parentElement.querySelector('.receiveWidthList');
var lengthSelect = selectElement.parentElement.querySelector('.receiveLengthList');
var type = selectElement.value;

widthSelect.innerHTML = "";
lengthSelect.innerHTML = "";

var defaultOption = document.createElement("option");
defaultOption.value = "none";
defaultOption.disabled = false;
defaultOption.selected = true;
defaultOption.required = true;
defaultOption.textContent = "select";

widthSelect.appendChild(defaultOption.cloneNode(true));
lengthSelect.appendChild(defaultOption.cloneNode(true));

if (type === "ribbon") {
populateDropdown(widthSelect, ribbonWidths);
populateDropdown(lengthSelect, ribbonLengths);
} else if (type === "foil") {
populateDropdown(widthSelect, foilWidths);
populateDropdown(lengthSelect, foilLengths);
}
}

function changeReceiveWidth(selectElement) {
var colourSelect = selectElement.parentElement.querySelector('.receiveColourList');
var width = selectElement.value;

colourSelect.innerHTML = "";

var defaultOption = document.createElement("option");
defaultOption.value = "none";
defaultOption.disabled = false;
defaultOption.selected = true;
defaultOption.required = true;
defaultOption.textContent = "select";

colourSelect.appendChild(defaultOption.cloneNode(true));

if (width === "10") {
populateDropdown(colourSelect, receiveColourList10);
} else if (width === "15") {
populateDropdown(colourSelect, receiveColourList15);
} else if (width === "25") {
populateDropdown(colourSelect, receiveColourList25);
} else if (width === "38") {
populateDropdown(colourSelect, receiveColourList38);
} else if (width === "100") {
populateDropdown(colourSelect, receiveColourList100);
} else if (width === "30") {
populateDropdown(colourSelect, receiveColourList30);
} else if (width === "55") {
populateDropdown(colourSelect, receiveColourList55);
} else if (width === "105") {
populateDropdown(colourSelect, receiveColourList105);
}
}

function populateDropdown(selectElement, optionsArray) {
for (var option of optionsArray) {
var optionElement = document.createElement("option");
optionElement.value = option;
optionElement.textContent = option;
selectElement.appendChild(optionElement);
}

}

function addNewReceiveItem() {
var newRow = document.createElement("div");
newRow.className = "receiveditems";
newRow.innerHTML = `
<div class="receiveditems" style="border:1px solid #096;margin:0.25em;">
<label>Type:</label>
<select class="receiveTypeList" name="type[]" onchange="changeReceiveType(this)" required>
<option value="none" selected disabled hidden>select</option>
<option value="ribbon">Ribbon</option>
<option value="foil">Foil</option>
</select>
<label>Width:</label>
<select class="receiveWidthList" name="width[]" onchange="changeReceiveWidth(this)" required>
<option value="none" selected disabled hidden>select</option>
</select>
<label>Length:</label>
<select class="receiveLengthList" name="length[]" required>
<option value="" selected disabled hidden>select</option>
</select>
<label>Colour:</label>
<select class="receiveColourList" name="colour[]" style="width:8em" required>
<option value="" selected disabled hidden>select</option>
</select>
<label>Cost:</label>
<input type="number" name="cost[]" step="0.01" placeholder="£0.00" maxlength="6" size="6" required>
<span class="newitemdelete" onclick="removeNewReceiveItem(this)">X</span>
<div>
`;
document.querySelector('#receiveditems').appendChild(newRow);
}

function removeNewReceiveItem(e){
e.parentElement.remove();
}
</script>

<div class="receiveditemsButton">
<button onclick="addNewReceiveItem()">Add New Row</button>
</div>
<div id="receiveditems" style="border:1px solid #F00;">
<div class="receiveditems" style="border:1px solid #096;margin:0.25em;">
<label>Type:</label>
<select class="receiveTypeList" name="type[]" onchange="changeReceiveType(this)" required>
<option value="none" selected disabled hidden>select</option>
<option value="ribbon">Ribbon</option>
<option value="foil">Foil</option>
</select>
<label>Width:</label>
<select class="receiveWidthList" name="width[]" onchange="changeReceiveWidth(this)" required>
<option value="none" selected disabled hidden>select</option>
</select>
<label>Length:</label>
<select class="receiveLengthList" name="length[]" required>
<option value="" selected disabled hidden>select</option>
</select>
<label>Colour:</label>
<select class="receiveColourList" name="colour[]" style="width:8em" required>
<option value="" selected disabled hidden>select</option>
</select>
<label>Cost:</label>
<input type="number" name="cost[]" step="0.01" placeholder="£0.00" maxlength="6" size="6" required>
</div>
</div>