Solved

Dynamically populating 3 select boxes

Posted on 2016-09-20
14
51 Views
Last Modified: 2016-09-27
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
Comment
Question by:StellaBob
  • 6
  • 6
  • 2
14 Comments
 
LVL 42

Expert Comment

by:zephyr_hex
Comment Utility
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
 

Author Comment

by:StellaBob
Comment Utility
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
 
LVL 21

Expert Comment

by:Kim Walker
Comment Utility
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
 
LVL 21

Expert Comment

by:Kim Walker
Comment Utility
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
 
LVL 21

Expert Comment

by:Kim Walker
Comment Utility
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
 

Author Comment

by:StellaBob
Comment Utility
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
 
LVL 21

Expert Comment

by:Kim Walker
Comment Utility
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
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

Author Comment

by:StellaBob
Comment Utility
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
 
LVL 42

Expert Comment

by:zephyr_hex
Comment Utility
Press F12 and look at the console tab.
0
 

Author Comment

by:StellaBob
Comment Utility
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
 
LVL 21

Accepted Solution

by:
Kim Walker earned 500 total points
Comment Utility
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
 

Author Comment

by:StellaBob
Comment Utility
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
 
LVL 21

Expert Comment

by:Kim Walker
Comment Utility
You are welcome.
0
 

Author Closing Comment

by:StellaBob
Comment Utility
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

How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

Join & Write a Comment

Introduction SQL Server Integration Services can read XML files, that’s known by every BI developer.  (If you didn’t, don’t worry, I’m aiming this article at newcomers as well.) But how far can you go?  When does the XML Source component become …
Load balancing is the method of dividing the total amount of work performed by one computer between two or more computers. Its aim is to get more work done in the same amount of time, ensuring that all the users get served faster.
This video shows how to set up a shell script to accept a positional parameter when called, pass that to a SQL script, accept the output from the statement back and then manipulate it in the Shell.
Viewers will learn how to use the INSERT statement to insert data into their tables. It will also introduce the NULL statement, to show them what happens when no value is giving for any given column.

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now