• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 72
  • Last Modified:

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.
0
StellaBob
Asked:
StellaBob
  • 6
  • 6
  • 2
1 Solution
 
zephyr_hex (Megan)DeveloperCommented:
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
0
 
StellaBobAuthor Commented:
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)
                              }
                          }
                        }
0
 
Kim WalkerWeb Programmer/TechnicianCommented:
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?
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
Kim WalkerWeb Programmer/TechnicianCommented:
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.
0
 
Kim WalkerWeb Programmer/TechnicianCommented:
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.
0
 
StellaBobAuthor Commented:
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.
0
 
Kim WalkerWeb Programmer/TechnicianCommented:
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.
0
 
StellaBobAuthor Commented:
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?
0
 
zephyr_hex (Megan)DeveloperCommented:
Press F12 and look at the console tab.
0
 
StellaBobAuthor Commented:
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.
0
 
Kim WalkerWeb Programmer/TechnicianCommented:
I appears that you changed the values of your country options from numbers to words which means that the cross reference is no longer necessary. So the only change to your original code would be the way the for loop is indexed. (See line 19)
				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 ( var x in ItemArray ) {
						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)
						}
					}
				}

Open in new window

However, I believe this will render your search function useless because the form will now submit names instead of numbers. Are the state/city arrays being generated from the database in Cold Fusion? If so, this means that the database is keyed on names instead of numbers and that the search just might still work now.
1
 
StellaBobAuthor Commented:
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!
0
 
Kim WalkerWeb Programmer/TechnicianCommented:
You are welcome.
0
 
StellaBobAuthor Commented:
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!
0

Featured Post

NFR key for Veeam Backup for Microsoft Office 365

Veeam is happy to provide a free NFR license (for 1 year, up to 10 users). This license allows for the non‑production use of Veeam Backup for Microsoft Office 365 in your home lab without any feature limitations.

  • 6
  • 6
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now