Avatar of StellaBob
StellaBob
Flag for United States of America asked on

Dynamically populating 3 select boxes

I currently have a website where visitors select a country drop down, which, based on their selection, populates the state drop down, then if they select a state, it populates a City drop down. The site's old, but the JavaScript still works.  I'm working on a new, responsive website, but this functionality isn't working.  It appears to be rendering queries properly and pulling the data that 'should' be accessed by the script, but the state/city drop downs are not working.  Here's the page where the selects work properly:  http://tieboss.com/DealerLocator.cfm.  

So here's my question for those of you who work in JavaScript.  The drop downs in the page I linked to above pulls 3 queries from 3 different tables.  A country table, a state table, and a city table.  These are connected by their respective 'IDs'.  So when you view the source, you'll see this scenario for each of the states.  The first numbers are the state IDS, and the "1" is the ID for for the country:

                 arrItems1['3'] = "AK";
             arrItemsGrp1['3'] = "1";
            
             arrItems1['198'] = "AK";
             arrItemsGrp1['198'] = "1";
            
             arrItems1['220'] = "AK";
             arrItemsGrp1['220'] = "1";
            
             arrItems1['221'] = "AK";
             arrItemsGrp1['221'] = "1";
            
             arrItems1['222'] = "AK";
             arrItemsGrp1['222'] = "1";

You'll see similar code for the states.  In my new version, I did what many of you would probably consider a no-no, but since the individual updating the data messsed it up so bad, I just have one table that contains one record for each dealer and instead of having fields that hold city/state/country IDs to connect to the other tables, I just included the city/state/country names in the table.  So, in the new scenario, the 3 queries pull and group things based on the actual city/state/country name.  So there are no 'IDs'.  So basically, what you see above, no renders like this:

                                 arrItems1['AK'] = "AK";
                         arrItemsGrp1['AK'] = "United States";
                        
                         arrItems1['AL'] = "AL";
                         arrItemsGrp1['AL'] = "United States";
                        
                         arrItems1['AR'] = "AR";
                         arrItemsGrp1['AR'] = "United States";
                        
                         arrItems1['AZ'] = "AZ";
                         arrItemsGrp1['AZ'] = "United States";

So...would this be why it doesn't work?  I don't know JavaScript to understand if the code is looking for numbers versus text.  If that doesn't matter, what would you need from me to help me further?

Let me know.  Thanks.
JavaScriptMicrosoft SQL Server

Avatar of undefined
Last Comment
StellaBob

8/22/2022 - Mon
zephyr_hex (Megan)

We need to see the selectChange() function in order to answer this.  That's the name of the JavaScript function that's run when one of those cascading drop downs changes.  You can see what I'm referring to by right clicking on one of those drop downs and selecting Inspect.

function
StellaBob

ASKER
Hopefully this is what you need:

function selectChange(control, controlToPopulate, ItemArray, GroupArray) {
                          var myEle ;
                          var x ;
                          // Empty the second drop down box of any choices
                          for (var q=controlToPopulate.options.length;q>=0;q--) controlToPopulate.options[q]=null;
                          if (control.name == "firstChoice") {
                              // Empty the third drop down box of any choices
                              for (var q=form.thirdChoice.options.length;q>=0;q--) form.thirdChoice.options[q] = null;
                          }
                          // ADD Default Choice - in case there are no values
                          myEle = document.createElement("option") ;
                          myEle.value = 0 ;
                          myEle.text = "None" ;
                          // controlToPopulate.add(myEle) ;
                          controlToPopulate.appendChild(myEle)
                          // Now loop through the array of individual items
                          // Any containing the same child id are added to
                          // the second dropdown box
                          for ( x = 0 ; x < ItemArray.length  ; x++ ) {
                              if ( GroupArray[x] == control.value ) {
                                myEle = document.createElement("option") ;
                                //myEle.value = x ;
                                myEle.setAttribute('value',x);
                                // myEle.text = ItemArray[x] ;
                                var txt = document.createTextNode(ItemArray[x]);
                                myEle.appendChild(txt)
                                // controlToPopulate.add(myEle) ;
                                controlToPopulate.appendChild(myEle)
                              }
                          }
                        }
                         
                        function selectChange(control, controlToPopulate, ItemArray, GroupArray) {
                          var myEle ;
                          var x ;
                          // Empty the second drop down box of any choices
                          for (var q=controlToPopulate.options.length;q>=0;q--) controlToPopulate.options[q]=null;
                          if (control.name == "firstChoice") {
                              // Empty the third drop down box of any choices
                              for (var q=form.thirdChoice.options.length;q>=0;q--) form.thirdChoice.options[q] = null;
                          }
                          // ADD Default Choice - in case there are no values
                          myEle=document.createElement("option");
                          theText=document.createTextNode("None");
                          myEle.appendChild(theText);
                          myEle.setAttribute("value","0");
                          controlToPopulate.appendChild(myEle);
                          // Now loop through the array of individual items
                          // Any containing the same child id are added to
                          // the second dropdown box
                          for ( x = 0 ; x < ItemArray.length  ; x++ ) {
                              if ( GroupArray[x] == control.value ) {
                                myEle = document.createElement("option") ;
                                //myEle.value = x ;
                                myEle.setAttribute("value",x);
                                // myEle.text = ItemArray[x] ;
                                var txt = document.createTextNode(ItemArray[x]);
                                myEle.appendChild(txt)
                                // controlToPopulate.add(myEle) ;
                                controlToPopulate.appendChild(myEle)
                              }
                          }
                        }
Kim Walker

Curious that you posted the function definition twice. At first I thought maybe you accidentally pasted it twice but there are subtle differences in the code. Do both of these appear in the same javascript file?
This is the best money I have ever spent. I cannot not tell you how many times these folks have saved my bacon. I learn so much from the contributors.
rwheeler23
Kim Walker

To answer my own question, I just looked at the source code and these are part of the embedded javascript. And they are consecutive in the script. You've copied and pasted them exactly as they appear in the embedded javascript.

For the record, you can delete the first one. The second one overwrites it.
Kim Walker

As far as the reason the new one won't work, you are correct in that the new data content would cause it to fail. I believe the simplest solution is to cross reference the country names and codes. See new lines 16 and 17 and a slight modification to what is now lines 21 and 22. This code is untested as I don't have enough of the data to properly test. If it still doesn't work, please post a link to the new page.
function selectChange(control, controlToPopulate, ItemArray, GroupArray) {
    var myEle ;
    var x ;
    // Empty the second drop down box of any choices
    for (var q=controlToPopulate.options.length;q>=0;q--) controlToPopulate.options[q]=null;
    if (control.name == "firstChoice") {
        // Empty the third drop down box of any choices
        for (var q=form.thirdChoice.options.length;q>=0;q--) form.thirdChoice.options[q] = null;
    }
    // ADD Default Choice - in case there are no values
    myEle=document.createElement("option");
    theText=document.createTextNode("None");
    myEle.appendChild(theText);
    myEle.setAttribute("value","0");
    controlToPopulate.appendChild(myEle);
    // array to cross-reference country name by number
    var groups = ["","United States","Canada"];
    // Now loop through the array of individual items
    // Any containing the same child id are added to
    // the second dropdown box
    for ( var x in ItemArray ) {
        if ( GroupArray[x] == groups[control.value] ) {
            myEle = document.createElement("option") ;
            //myEle.value = x ;
            myEle.setAttribute("value",x);
            // myEle.text = ItemArray[x] ;
            var txt = document.createTextNode(ItemArray[x]);
            myEle.appendChild(txt)
            // controlToPopulate.add(myEle) ;
            controlToPopulate.appendChild(myEle)
        }
    }
} 

Open in new window

I will refrain from any other comments other than to say this code could be rewritten to be a lot more efficient; especially in the array definition procedure.
StellaBob

ASKER
Sorry it took me so long, I had to publish it to a test spot as I'm still working on the site.  Note, the actual 'search' won't work yet....I was just trying to get the dang select boxes to work right on this page.  Here's a link to the new page:  http://icbits.com/tieboss/DealerLocator.cfm.  I removed the first javascript and replaced the second one with your code, but it's still not working.  Hopefully you'll be able to see the issue right away.  Thank you so much for looking at this for me.
⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.
Kim Walker

The page is producing 3 javascript errors as it loads.

Two of them are related to the absence of the jQuery library. It seems you have scripts that depend on jQuery being processed before jQuery is being loaded. It is a good idea for the jQuery load scripts to be the first scripts in your document. These are currently on lines 92, 93, and 96. They need to be moved up above the modal.js script tag which is currently on line 89. However, the jQuery load script on line 96 is part of an IE conditional block. You might try leaving it where it is for now, then testing the page in IE9 or newer.
      <script src="js/jquery.js"></script>
      <script src="js/jquery-migrate-1.2.1.js"></script>
      
      	  <script src="js/modal.js"></script>
  		  <script src="js/TMForm.js"></script>

Open in new window


The third is an error in the city name array definition. You have a city name with an apostrophe which is terminating the array key name string early, Coeur d' Alene. If there is a way in Cold Fusion to add escape characters to your data, That would be the best way to handle this. You could also change the single quotes that currently surround the key names in the arrays to double quotes. Ultimately you would want either of the following results:
1
				 arrItems2['Coeur d\' Alene'] = "Coeur d' Alene";
				 arrItemsGrp2['Coeur d\' Alene'] = "ID";

Open in new window

2
				 arrItems2["Coeur d' Alene"] = "Coeur d' Alene";
				 arrItemsGrp2["Coeur d' Alene"] = "ID";

Open in new window

When these errors are eliminated, we can look at the selectChange function to see if it's working.
StellaBob

ASKER
Well, here's the funky thing...the old website doesn't pull in any other .js files.  Well one, but when it's deleted on my local, it doesn't affect anything.  I also tried commenting each .js file one at a time, wondering if something was conflicting (which I've encountered), but it still didn't work.  

Next, I wanted to see if the single quotes could be changed to double...to see if that mattered.  I figured it would be easier to do that then to try to find some work around or retain people to no use single quotes.  I changed them on the old site and the code still worked, so I tried that on the new site, and it still doesn't work.  Would it still matter if it was arrItems2["Cour d' Alene"]?  Would the single quote still muck things up?

Finally, I went into the database and removed all of the quotes and extra commas I found, but no luck.  I published the revised pages so you could take a look at that.

Question...how do I turn on JavaScript error checking in Chrome?
zephyr_hex (Megan)

Press F12 and look at the console tab.
Your help has saved me hundreds of hours of internet surfing.
fblack61
StellaBob

ASKER
Thanks Zephyr...I use Inspect all the time, but didn't know that's were the errors were.  They used to just pop up, but now I know.

And, if either of you have a better option for me...perhaps a newer version of code that you'd recommend, I would do that.  I tried searching, but encountered the same problem with other code.  So maybe it's the way I'm pulling things?  Let me know.  Thanks.
ASKER CERTIFIED SOLUTION
Kim Walker

THIS SOLUTION ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
GET A PERSONALIZED SOLUTION
Ask your own question & get feedback from real experts
Find out why thousands trust the EE community with their toughest problems.
StellaBob

ASKER
Kim you are AWESOME!!!!  Thank you so much for your help.  And yes, I knew I need to change the results page.  This was the initial issue I needed to resolve.  Again, thank you soooo much!
Kim Walker

You are welcome.
⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.
StellaBob

ASKER
This is why I pay for this forum.  Not only do I typically get the answers I need, but it's usually done in a professional manner.  I remember, years ago, a business partner of mine asked a question on another forum only to be berated by another poster.  This makes no sense to me as there will always be new programmers, or programmers not proficient in every language.  So getting assistance from people who not only can do so in a professional manner, but who can also help without making the person feel 'dumb' is how it should be.  Thanks again Kim!