Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

228
Views
Replacing options on <select> dynamically from JavaScript array

In a bespoke shopping cart, I pull from my database a list of options that a particular product has. The number of these options can vary by product. I then turn that list of options into a JavaScript array.

An example with 3 options:

{"Small":{"Super":{"Pack":"parta","Case":"parte"},"Maxi":{"Pack":"partb","Case":"partf"}},"Large":{"Super":{"Pack":"partc","Case":"partg"}},"X Large":{"Maxi":{"Pack":"partd"}}}

Using the above, I would now like to generate an HTML select field, listing all the "first" options:

<select>
<option value="Small">Small</option>
<option value="Large">Large</option>
<option value="X Large">X Large</option>
</select>

Once the user has selected the first option, I then need another <select> box to then load with options that are available for their selection. So, if they selected "Small" from above, the new select box would be:

<select>
<option value="Super">Super</option>
<option value="Maxi">Maxi</option>
</select>

Finally, when they select from this list, a 3rd select box loads in the final options, along with the part numbers as values:

<select>
<option value="parta">Pack</option>
<option value="parte">Case</option>
</select>

The number of options can vary, from zero to 4. But, each time when options are available, I need to pull the part number based on the users selection. The part number doesn't necessarily need to be the value of the last select, it can be pushed to a new hidden variable.

I can achieve this using ajax, by making an ajax call every time a selection is chosen, but can it be done via JavaScript / jQuery, without having to make ajax calls, given that the array is on the page and available to use?

about 4 years ago · Juan Pablo Isaza
2 answers
Answer question

0

When you dynamically create the select element, also determine which "node" in your tree structure goes with that element, and use it to:

  • add a default "Please select..." option to the select element
  • populate the select element further with the real options
  • determine the deeper node when an option is selected (also when the initial selection is made when the element is created), and use it to create the next select element with the same function
  • This cascade stops when the deeper node does not exist (when "Please select..." is selected) or it happens to be a string and not an object.

Here is some code for inspiration:

let optionTree = {"Small":{"Super":{"Pack":"parta","Case":"parte"},"Maxi":{"Pack":"partb","Case":"partf"}},"Large":{"Super":{"Pack":"partc","Case":"partg"}},"X Large":{"Maxi":{"Pack":"partd"}}};

let container = document.querySelector("#container");

addSelector(optionTree);

function addSelector(node) {
    let select = document.createElement("select");
    // Start with the default option:
    let option = document.createElement("option");
    option.text = "Please select...";
    select.add(option);
    for (let key in node) { // Populate the select element
        let option = document.createElement("option");
        option.value = key;
        option.text = key;
        select.add(option);
    }
    container.appendChild(select); // Add it to the page

    function change() {
        // Remove select elements that come after the selection
        while (select.nextElementSibling) {
            select.nextElementSibling.remove();
        }
        let key = select.value;
        if (node[key] && typeof node[key] !== "string") {
            addSelector(node[key]); // Create the next select element(s)
        }
    }
    // Call the above function whenever a selection is made
    select.addEventListener("change", change);
    change(); // ... and also call it now
}
<div id="container"></div>

about 4 years ago · Juan Pablo Isaza Report

0

Assuming you already have the three select elements in the DOM, you can populate the first select, and add a change event listener to both the first and second to achieve this. Try this

let $s1 = document.querySelector('#select-1');
let $s2 = document.querySelector('#select-2');
let $s3 = document.querySelector('#select-3');

let object = {"Small":{"Super":{"Pack":"parta","Case":"parte"},"Maxi":{"Pack":"partb","Case":"partf"}},"Large":{"Super":{"Pack":"partc","Case":"partg"}},"X Large":{"Maxi":{"Pack":"partd"}}};

// add options to first select
$s1.innerHTML = '<option></option>'; // empty select
Object.keys(object).forEach(val => $s1.append(new Option(val, val))); // append children
$s1.dispatchEvent(new Event('change')); // trigger change event

// listen to change event on first select/get options for second select
$s1.addEventListener('change', function(e){
    $s2.innerHTML = '<option></option>'; // empty select

    // append children
    Object.keys(object[e.target.value] ?? []).forEach(val => {
        $s2.appendChild(new Option(val, val));
    });

    // trigger change event
    $s2.dispatchEvent(new Event('change'));
});

// listen to change event on second select/get options for third select
$s2.addEventListener('change', function(e){
    $s3.innerHTML = '<option></option>'; // empty select

    // append children
    Object.entries(object[$s1.value]?.[e.target.value] ?? []).forEach(([key, val]) => {
        $s3.appendChild(new Option(key, val));
    });
});
select {min-width:80px}
<select id="select-1"></select>
<select id="select-2"></select>
<select id="select-3"></select>

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!