简体   繁体   中英

Why aren't third and fourth boxes in this cascading drop-downs javascript not populating?

Should be very simple cascading dropdowns, the the third and fourth dropdowns are populating.

Selection from first dropdown populates second dropdown as expected. But selection from second dropdown does not impact third or fourth dropdown.

I'm sure I've missed something obvious but I can't find it. Any help appreciated.

 <html> <head> <script type="text/javascript"> var clientPlus = { "Client A": { "Transactional": { "Single": ["Successful", "Busted"], "Third Party": ["Successful", "Busted"], "Joint": ["Successful", "Busted"] }, "Monthly": { "Single": ["Successful", "Busted"], "Third Party": ["Successful", "Busted"], "Joint": ["Successful", "Busted"] } }, "Client B": { "Transactional": { "Single": ["Successful", "Busted"], "Third Party": ["Successful", "Busted"], "Joint": ["Successful", "Busted"] }, "Monthly": { "Single": ["Successful", "Busted"], "Third Party": ["Successful", "Busted"], "Joint": ["Successful", "Busted"] } }, "Client C": { "Transactional": { "Single": ["Successful", "Busted"], "Third Party": ["Successful", "Busted"], "Joint": ["Successful", "Busted"] }, "Monthly": { "Single": ["Successful", "Busted"], "Third Party": ["Successful", "Busted"], "Joint": ["Successful", "Busted"] } } } window.onload = function() { //Get html elements var clientSel = document.getElementById("clientSel"); var invoicetypeSel = document.getElementById("invoicetypeSel"); var payerSel = document.getElementById("payerSel"); var sorbSel = document.getElementById("sorbSel"); //Load clients for (var client in clientPlus) { clientSel.options[clientSel.options.length] = new Option(client, client); } //client Changed clientSel.onchange = function() { invoicetypeSel.length = 1; // remove all options bar first payerSel.length = 1; // remove all options bar first sorbSel.length = 1; // remove all options bar first if (this.selectedIndex < 1) return; // done for (var invoicetype in clientPlus[this.value]) { invoicetypeSel.options[invoicetypeSel.options.length] = new Option(invoicetype, invoicetype); } } //Invoice Type Changed invoicetypeSel.onchange = function() { payerSel.length = 1; // remove all options bar first sorbSel.length = 1; // remove all options bar first if (this.selectedIndex < 1) return; // done for (var payer in clientPlus[this.value]) { payerSel.options[payerSel.options.length] = new Option(payer, payer); } } //Payer Changed payerSel.onchange = function() { sorbSel.length = 1; // remove all options bar first if (this.selectedIndex < 1) return; // done var sorbs = clientPlus[clientSel.value][invoicetypeSel.value][this.value]; for (var i = 0; i < sorbs.length; i++) { sorbSel.options[sorbSel.options.length] = new Option(sorbs[i], sorbs[i]); } } } </script> </head> <body> <form name="myform" id="myForm"> <select id="clientSel" size="1"> <option value="" selected="selected">Select Client:</option> </select> <br> <br> <select id="invoicetypeSel" size="1"> <option value="" selected="selected">Select Invoice Type:</option> </select> <br> <br> <select id="payerSel" size="1"> <option value="" selected="selected">Select Payer Type:</option> </select> <br> <br> <select id="sorbSel" size="1"> <option value="" selected="selected">Successful or Busted?</option> </select> </form> </body> </html> 

https://jsfiddle.net/mbps1/bt9m3qoj/1/

inside invoicetypeSel.onchange , your for is getting values from clientPlus[Second Value] you are forgetting to also supply the first value of your object.

for (var payer in clientPlus[clientSel.value][this.value]) {
    payerSel.options[payerSel.options.length] = new Option(payer, payer);
}

The control conditions for both for cyles in clientSel.onchange and invoiceTypeSel.onchange are the same. In other words, they are iterating over the same key value pairs in both cases (ie cientPlus[some ID] ). In the first case, when populating 'invoiceType' based on client selection, it is fine since you'll get an object with two attributes: Monthly and Transactional (each referencing an object), but in the second case, when you want to populate 'playerType', it's hardly satisfying to use the same cycle. Instead, you want to iterate over the object one level deeper : clientPlus[some ID][whatever the selection for invoiceType was] .

It should be noted however, that this data structure seems redundant. Values that are the same and repeating over and over would be better stored once only.

 <html> <head> <script type="text/javascript"> var clientPlus = { "Client A": { "Transactional": { "Single": ["Successful", "Busted"], "Third Party": ["Successful", "Busted"], "Joint": ["Successful", "Busted"] }, "Monthly": { "Single": ["Successful", "Busted"], "Third Party": ["Successful", "Busted"], "Joint": ["Successful", "Busted"] } }, "Client B": { "Transactional": { "Single": ["Successful", "Busted"], "Third Party": ["Successful", "Busted"], "Joint": ["Successful", "Busted"] }, "Monthly": { "Single": ["Successful", "Busted"], "Third Party": ["Successful", "Busted"], "Joint": ["Successful", "Busted"] } }, "Client C": { "Transactional": { "Single": ["Successful", "Busted"], "Third Party": ["Successful", "Busted"], "Joint": ["Successful", "Busted"] }, "Monthly": { "Single": ["Successful", "Busted"], "Third Party": ["Successful", "Busted"], "Joint": ["Successful", "Busted"] } } } window.onload = function() { //Get html elements var clientSel = document.getElementById("clientSel"); var invoicetypeSel = document.getElementById("invoicetypeSel"); var payerSel = document.getElementById("payerSel"); var sorbSel = document.getElementById("sorbSel"); //Load clients for (var client in clientPlus) { clientSel.options[clientSel.options.length] = new Option(client, client); } //client Changed clientSel.onchange = function() { invoicetypeSel.length = 1; // remove all options bar first payerSel.length = 1; // remove all options bar first sorbSel.length = 1; // remove all options bar first if (this.selectedIndex < 1) return; // done for (var invoicetype in clientPlus[this.value]) { invoicetypeSel.options[invoicetypeSel.options.length] = new Option(invoicetype, invoicetype); } } //Invoice Type Changed invoicetypeSel.onchange = function() { payerSel.length = 1; // remove all options bar first sorbSel.length = 1; // remove all options bar first if (this.selectedIndex < 1) return; // done for (var payer in clientPlus[clientSel.options[clientSel.selectedIndex].value][this.value]) { payerSel.options[payerSel.options.length] = new Option(payer, payer); } } //Payer Changed payerSel.onchange = function() { sorbSel.length = 1; // remove all options bar first if (this.selectedIndex < 1) return; // done var sorbs = clientPlus[clientSel.value][invoicetypeSel.value][this.value]; for (var i = 0; i < sorbs.length; i++) { sorbSel.options[sorbSel.options.length] = new Option(sorbs[i], sorbs[i]); } } } </script> </head> <body> <form name="myform" id="myForm"> <select id="clientSel" size="1"> <option value="" selected="selected">Select Client:</option> </select> <br> <br> <select id="invoicetypeSel" size="1"> <option value="" selected="selected">Select Invoice Type:</option> </select> <br> <br> <select id="payerSel" size="1"> <option value="" selected="selected">Select Payer Type:</option> </select> <br> <br> <select id="sorbSel" size="1"> <option value="" selected="selected">Successful or Busted?</option> </select> </form> </body> </html> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM