Home > Mobile >  JavaScript Dynamic Dropdowns
JavaScript Dynamic Dropdowns

Time:08-09

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);

  • Related