I have a value returned from a Promise function. The returned value is ctis
in the example. I then use the reduce
method to return the object into the format I need.
What I need is to create three dropdown boxes that dynamically change their options based on the previously selected option from the previous select. I need the options to be populated from ctisData
. The caveat to this is that Category key & Type keys will be not be the same as in the example. They can be lots of different values. How can I accomplish this?
const ctis = [
"Category1 / C1-Type1 / C1-T1-Item1",
"Category1 / C1-Type1 / C1-T1-Item2",
"Category1 / C1-Type1 / C1-T1-Item2",
"Category1 / C1-Type1 / C1-T1-Item3",
"Category1 / C1-Type2 / C1-T2-Item1",
"Category1 / C1-Type2 / C1-T2-Item2",
"Category1 / C1-Type2 / C1-T2-Item3",
"Category2 / C2-Type1 / C2-T1-Item1",
"Category2 / C2-Type1 / C2-T1-Item2",
"Category2 / C2-Type1 / C2-T1-Item2",
"Category2 / C2-Type1 / C2-T1-Item3",
"Category2 / C2-Type2 / C2-T2-Item1",
"Category2 / C2-Type2 / C2-T2-Item2",
"Category2 / C2-Type2 / C2-T2-Item3",
];
const ctisData = ctis.reduce(
(obj, line) => {
const [category, type, item] = line.split(" / ");
obj[category] = {
...obj[category]
}
obj[category][type] = [...new Set([...obj[category][type] || [], item])];
return obj;
}, {});
console.log(ctisData);
var x = document.createElement("SELECT");
x.setAttribute("id", "mySelect");
document.body.appendChild(x);
var z = document.createElement("option");
z.setAttribute("value", "category");
var t = document.createTextNode("Category");
z.appendChild(t);
document.getElementById("mySelect").appendChild(z);
var x2 = document.createElement("SELECT");
x2.setAttribute("id", "mySelect2");
document.body.appendChild(x2);
var z2 = document.createElement("option");
z2.setAttribute("value", "type");
var t2 = document.createTextNode("Type");
z2.appendChild(t2);
document.getElementById("mySelect2").appendChild(z2);
var x3 = document.createElement("SELECT");
x3.setAttribute("id", "mySelect3");
document.body.appendChild(x3);
var z3 = document.createElement("option");
z3.setAttribute("value", "item");
var t3 = document.createTextNode("Item");
z3.appendChild(t3);
document.getElementById("mySelect3").appendChild(z3);
<html>
<body>
</body>
</html>
CodePudding user response:
Made you a few utility functions. Then I went all the way to make a working example.
const ctis = [
"Category1 / C1-Type1 / C1-T1-Item1",
"Category1 / C1-Type1 / C1-T1-Item2",
"Category1 / C1-Type1 / C1-T1-Item2",
"Category1 / C1-Type1 / C1-T1-Item3",
"Category1 / C1-Type2 / C1-T2-Item1",
"Category1 / C1-Type2 / C1-T2-Item2",
"Category1 / C1-Type2 / C1-T2-Item3",
"Category2 / C2-Type1 / C2-T1-Item1",
"Category2 / C2-Type1 / C2-T1-Item2",
"Category2 / C2-Type1 / C2-T1-Item2",
"Category2 / C2-Type1 / C2-T1-Item3",
"Category2 / C2-Type2 / C2-T2-Item1",
"Category2 / C2-Type2 / C2-T2-Item2",
"Category2 / C2-Type2 / C2-T2-Item3",
];
const ctisData = ctis.reduce(
(obj, line) => {
const [category, type, item] = line.split(" / ");
obj[category] = {
...obj[category]
}
obj[category][type] = [...new Set([...obj[category][type] || [], item])];
return obj;
}, {});
// console.log(ctisData);
function get_categories() {
return Object.keys(ctisData)
}
function get_types_by_category(category) {
return ctisData[category] ? Object.keys(ctisData[category]) : []
}
function get_items_by_type_by_category(type, category) {
return ctisData[category] && ctisData[category][type] ? Object.values(ctisData[category][type]) : []
}
function do_select(select, options) {
select.innerHTML = '<option>Choose</options>';
options.forEach(function(value) {
var z = document.createElement("option");
z.setAttribute("value", value);
z.innerText = value;
select.appendChild(z)
})
}
var sel_category = document.createElement("SELECT");
sel_category.setAttribute("id", "category");
document.body.appendChild(sel_category);
do_select(sel_category, get_categories())
sel_category.addEventListener('change', function() {
do_select(sel_type, get_types_by_category(sel_category.value))
do_select(sel_item, get_items_by_type_by_category(sel_type.value, sel_category.value))
})
var sel_type = document.createElement("SELECT");
sel_type.setAttribute("id", "type");
document.body.appendChild(sel_type);
sel_type.addEventListener('change', function() {
do_select(sel_item, get_items_by_type_by_category(sel_type.value, sel_category.value))
})
var sel_item = document.createElement("SELECT");
sel_item.setAttribute("id", "category");
document.body.appendChild(sel_item);