Expand my Community achievements bar.

Multiple Dependent Dropdown Menus in ES3

Avatar

Level 2

Hello!

 

I know this question has been asked in the past before, but I cannot find a clear step-by-step solution for what I would like to accomplish.

 

I need to have three dropdown menus where two are dependent on the previous dropdown menu selections. For example, using vehicles: Year, Make, Model. The Year dropdown would have a list of the years, the Make dropdown would base the vehicle manufacturer shown on what was selected in the Year dropdown (some manufacturers did not exist in certainyears), and the Model dropdown would base the vehicle models shown on what was selected in the Make dropdown. A similar scenario would apply with Countries, State, Cities.

 

What would be the easiest way to accomplish this? I have tried switch statements on both exit and pre-open for the dropdowns, but always end up with a pop-up warning that the field "cannot be left blank" upon selecting the dropdown arrow for the second dropdown box.

 

Thank you!

37 Replies

Avatar

Level 10

Right, this is an issue where you'd have to add in the if statement that the right continent is also selected when showing the cities...

 

I can understand that all this may be time consuming, because you need to create a list of cities for each country. And then creating the righteous if statements along with show/hide the right fields.

And if you have to make them fields required with validation, it will be even harder to comply as you have hidden fields that are required. This solution is not quite the best option for you.

You will likely have to work with 1 drop down for each (Continent, countries, cities) and alter the list based on the option selected.

 

To do so, you will need to either work with Arrays or JSON object to create a hierarchical list that will gather the appropriate list automatically based on the selected item.

I can provide a sample on how to achieve this, you can start checking how to build a JSON Object or arrays if you wish.

 

You can also check on this object generator, check its demo to see how it works, it might help you achieve to build the object you want with all the continents, countries and cities.

http://www.objgen.com/json

 

 

Avatar

Level 10
Go on and build your JSON object with this template, once you have a good template with some countries assigned to continents and cities assigned to countries, let me know. http://www.objgen.com/json/models/3b0uZ

Avatar

Level 2

Hi Magus069! Sorry this again took a long time, but work has been busy. I have completed the template you posted. It is at the same location: http://www.objgen.com/json/models/3b0uZ

 

I hope this is enough information for you to guide me with setting my form up. Thank you again for your assistance with this. Much appreciated!

Avatar

Level 10

When creating the JSON object you have to make sure that each key does not contain a space, make sure to replace it with an underscore "_". Otherwise it will not work properly.

Exemple: North America > North_America

New Zealand > New_Zealand

United States > United_States

 

This is only for the KEYS of an JSON Object. The values that are within an Array displayed like (Cities [] = bla,bla,bla) does not need an underscore, because these are the values that will be displayed in the drop down lists.

Here is the link to the form I've been working on to make it work. https://gofile.io/d/aKWpEc

Simply make sure that the JSON object you are working on contains the right values at the right places and it will work like a charm.

 

If you have any question let me know.

 

Avatar

Level 2
I was responding as you were still typing. Thanks for the explanation regarding what keys are. I will fix them and look at the form you linked. I should be able to work on this steadily from now on, so no more long gaps in responding. Thanks again!

Avatar

Level 2

Hi Magus069!

 

I was looking at the form you posted and reviewing the code that was added to try and understand it. Just to confirm, did you add the three sub-forms at the bottom with the new code so that they can be compared with the previous ones above? I will continue to review and test it. This is all a learning experience for me.

 

Now, is there a way to reset the Cities drop-down to display blank or clear if the Countries drop-down is changed? Likewise, if I change the Continent drop-down to something else, can both the Country and Cities drop-downs be reset to display blank or clear? Maybe both things can be achieved by setting the default view to blank and resetting the drop-down to that every time something in a previous drop-down changes.

 

Thank you!

Avatar

Level 10

I'm sorry I forgot to remove the old drop down lists.

 

Yes you can clear the drop down lists right before I call the execInitialize event from the exit event of the previous drop down lists.

You can clear the lists using the following method:

ddSelCity.clearItems();

You can remove the default value that is in cities drop down if you wish which will leave it blank.

You can also remove the selected values after clearing the list items from the drop down lists by doing the following:

ddSelCity.rawValue = null;

 I hope this will help.

Avatar

Level 2

I am trying the best I can to understand the code that you added to the form and the drop-downs. I feel that I will have a better grasp of this once I know what each part of the code does.

 

Initialize code for Country drop-down:

 form1.#subform[0].frmCountry.ddSelContinent::initialize - (JavaScript, client)

if (frmContinent.ddContinent.selectedIndex >= 0){
	var arrCountries = objData.getCountries(frmContinent.ddContinent.getDisplayItem(frmContinent.ddContinent.selectedIndex));
	this.setItems(arrCountries.join(","));
} else{
	this.clearItems();

 

Initialize code for Cities drop-down:

 form1.#subform[0].frmCity.ddSelCountry::initialize - (JavaScript, client)

if (frmContinent.ddContinent.selectedIndex >= 0 && frmCountry.ddSelContinent.selectedIndex >= 0){
	var arrCities = objData.getCities(frmContinent.ddContinent.getDisplayItem(frmContinent.ddContinent.selectedIndex), frmCountry.ddSelContinent.getDisplayItem(frmCountry.ddSelContinent.selectedIndex));
	this.setItems(arrCities.join(","));
} else{
	this.clearItems();

 

Functions in objData variable:

function getContinents(){
	var arrContinents = new Array();
	for (var continent in myData){
		arrContinents.push(myData[continent].name);
	}
	return arrContinents;
}

function getCountries(strContinent){
	var strContinentValue = strContinent.replace(/ /g, "_");
	return myData[strContinentValue].Countries;
}

function getCities(strContinent, strCountry){
	var strContinentValue = strContinent.replace(/ /g, "_"),
		strCountryValue = strCountry.replace(/ /g, "_");
	return myData[strContinentValue][strCountryValue].Cities;

 

I know that this is pretty much everything you added, but I am really trying to understand the code. I do not want to just copy/paste and be done with it, I want to know what these do so that I can learn to apply them properly. I do not expect you to explain these to me, you have already helped me so much. But if you want, then go ahead. That would be great! Otherwise, do you know where I could find more information about what these do? Thanks again!

Avatar

Level 2

Hi Magus069!

 

I managed to understand most of the code, with a few things that I am still working on, especially with the functions. My form is working great, as you expected. There are a few things that I wanted to ask before I complete it:.

 

I inserted the code in the exit event of the previous drop-down menu (before the initialize) using:

 

ddSelCity.clearItems();

 

However, this leaves the previously selected item visible and does not make the drop-down show its default value (e.g., "Select Country". Maybe it clears the drop-down items but not the visible ones? Is this how it should work?

 

I then added:

 

ddSelCity.rawValue = null;

 

This clears the visible value because it sets it to "null", which is good, but I would like to show the default value again, at least for the Cities drop-down. I managed to do it by using:

 

ddSelCity.rawValue = "Select Country";​

 

This works fine, since I am telling the drop-down object what to show textually. But I am sure there is a better way to call the default value set in the drop-down. Is there a way to actually tell the drop-down to show its default value set within the object vs. telling it what to show textually?

 

Once I sort the above, I would like to be able to have the drop-downs not reset the next one if you click on it but do not change the selection. For example, if I have Canada selected under Countries drop-down and Toronto under Cities, and I go and click the countries drop-down but change my mind and leave Canada on there, it resets the Cities because of the exit event (resets to either blank or my text above, pending updated code). Is there a way for code to evaluate if the selection has changed before triggering the reset of the next drop-down during the exit process?

 

Finally, all three drop-downs are required for this form. The form gives me an error every time I select something in a drop-down, telling me that the next drop-down cannot be left blank. Is there a way to do this check in some other way (e.g., using submit button on form) so that it does not interfere with the selection process of the drop-down menus?

 

Thanks again for your help!

Avatar

Level 10

You made it through like a boss so far, good job.

I should've left comments for all the code that I wrote for you, I'm sorry for that I can still do it if you still wish me to explain some more.

 

If you wish to evaluate if the value has been changed, I suggest one of two different ways to do this and one of them is within the change event. This would require a bit more tweaking.

Another way would be this way: have a separate field that is hidden in background and have the value changed every time you exit the drop down field. When exiting the field simply verify, before executing anything code, if the value in the hidden field is the same as the selected value on the exit event. Hidden text field will do the job.

 

And for the validation message, I never really worked out that way I would need to dive in the software built-in validation to check how you can fix this; or have a look at what you already have implemented.

Avatar

Level 2

Hi there! Thanks for the encouragement. If you have time and wish to explain the code further, especially the functions, that would be great.

 

Your suggestion about using hidden fields to identify a change in the drop-down menu value worked perfectly! I was able to take care of that on my form without issues, though I am sure the other way (i.e., using the change event) would have been an interesting option. I tried to search for more information on that, but was unsuccessful.

 

The only thing that is left for me to do is to figure out the required fields issue. In summary, the 3 drop-down menus are required fields on this form and show up with a red outline when in Acrobat. The problem I am having is that, for example, when I select a Continent from the drop-down, it immediately warns me that the Country drop-down is required. I believe this is due to the initialize event for the Country drop-down occurring during the exit event for the Continent drop-down, but I could be wrong. The same thing happens for the City drop-down when selecting from the Country drop-down. Is there a way to prevent these pop-ups from happening but at the same time requiring these drop-down menus to be selected? Maybe something could be done right when one clicks on the Submit by Email button that I have on the form so that it verifies that those drop-down menus have values.

 

Thanks again for all your help!

Avatar

Level 10

I don't know maybe you could try to remove the validation when filling those fields and on the mouseDown event of the submit you set them back to execute validation.

 

I believe the code you'd need would be:

//removing validation
ddCountry.validate.nullTest = "disabled";
//and adding validation
ddCountry.validate.nullTest = "error";

Avatar

Level 10
Here is the document with the comments for the code I provided you with. Let me know if you have any questions. https://gofile.io/d/grIHCk

Avatar

Level 2

Hi Magus069!

I tried to check the file that you uploaded, but the folder seems empty. Maybe I took too long to access it. Would you mind reposting it?

 

I used your suggestions and managed to work around the pop up issue in the form. I am now able to validate the form fields properly, with a different approach depending on the field.

 

One last thing that I need help with is getting the signature box (which takes a digital signature from a certificate) to be required before the form is allowed to submit. I implemented the code at the end of this post https://experienceleaguecommunities.adobe.com/t5/adobe-livecycle-discussions/how-to-make-signature-f... and it works for requiring the signature before submitting. However, it still will not let me submit as the field still shows a validation failed error even though it has a digital signature in place.

 

Thanks again for all your help!

Avatar

Level 10
Hi, sorry for the delay, you can try the gofile link once again, the file should be there. For the signature validation it is sketchy... I've already managed to get some work done with the fields but it is not that easy. A digital signature can't be verified in any given event. It's very specific to certain events. There's too many security restrictions related to the field that it is not very friendly to work around with its data.