I have some code below that displays two selects. The Name Select is filtered based on the option selected in the Tag Select.
This is all fine, however, I would like to keep a default option in the Name Select even after a tag has been selected.
Something like "Please Select" as the first option regardless of what is chosen in the Tags Select. - I still want the current functionality to remain so after clicking the Tags Select it will still show options in the Names Select based on what is Selected in the Tags Select.
Basically it will function as it does now but have a default option as the first option for names.
UPDATE: code below has been updated with the answer @CharlesEF provided, and it works for the first part of this question. However, since the answer was provided in a reply I could not mark as correct.
I've included updated code with an additional problem below. I need the price output to revert to null or a default value if the default Name or Tag option "please select" is selected.
With the current code, price output stays current with the previously selected name when the "please select" option is selected for Name or Tag.
let result = [{
name: "some name",
tag: "some tag",
price: "50"
},
{
name: "some name1",
tag: "some tag1",
price: "10"
},
{
name: "some name1-2",
tag: "some tag1",
price: "20"
},
{
name: "some name2",
tag: "some tag2",
price: "30"
},
{
name: "some name2-2",
tag: "some tag2",
price: "40"
}
];
//Generic function to fill a dropdown with options
let populateDropDown = (params) => {
let set = new Set()
params.optionsToPopulate.forEach(item => {
const txt = item[params.text];
if (!set.has(txt)) {
params.element.add(new Option(txt, txt))
set.add(txt);
}
})
}
//Initialize tags dropdown
(function() {
document.getElementById("tags").addEventListener('change', (event) => {
tagChanged(event);
});
let params = {
optionsToPopulate: result,
element: document.getElementById("tags"),
id: "tag",
text: "tag"
}
populateDropDown(params);
})();
//Tags dropdown change event.
let tagChanged = (event) => {
let tagValue = event.target.value;
//filter the results based on the value of tags dropdown
let optionsToAdd = result.filter(item => item.tag === tagValue);
let names = document.getElementById("names");
names.options.length = 1;
let params = {
optionsToPopulate: optionsToAdd,
element: names,
id: "name",
text: "name"
}
populateDropDown(params);
}
//Function to place price in span
let populatePrice = (params) => {
params.priceToPopulate.forEach((item) => {
params.spanElement.innerHTML =
(item[`${params.text}`], item[`${params.text}`]);
});
};
//Initialize price span
(function () {
names.addEventListener("change", (event) => {
nameChanged(event);
});
})();
//Names dropdown change event.
let nameChanged = (event) => {
let nameValue = event.target.value;
//Filter URL results based on the value of names dropdown
let priceToAdd = result.filter((item) => item.name === nameValue);
let priceSpan = document.getElementById("price");
let params = {
priceToPopulate: priceToAdd,
spanElement: priceSpan,
id: "price",
text: "price",
};
populatePrice(params);
};
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
Tags:
<select id="tags">
<option value="please select">please select</option>
</select>
<br><br><br> Names:
<select id="names">
<option value="please select">please select</option>
</select>
<br><br><br> Price:
<span id="price"></span>
</body>
</html>
1st option Hard code the default 1st option in the HTML markup, then use 'names.options.length = 1;'. This will keep the default 1st option.
2nd option Add the default 1st option in Javascript, before the loop to fill in names.
Your span needs to be cleared with javascript. Just add 1 line of code, 'document.getElementById("price").innerHTML = "";'. You can put this line in the 'tagChanged' function or in the function that populates the dropdown.
EDIT:
If you want to clear 'price' when the 1st option is selected then you need to add an if test in the 'tagChanged' function. Test if the option value equals the value of the default 1st option. If yes, clear the span.
Glad this helped.