These forums are now Read Only. If you have an Acrobat question, ask questions and get help from one of our experts.

Looping through a multi dimensional array to populate 3 dropdowns

smartin
Registered: Mar 3 2008
Posts: 5

I am (new to) using LiveCycle Designer 7 and javascript and am trying to populate 3 dependent dropdowns in a subform using a multidimensional array. I am having trouble getting the second layer of my array into the second dropdown, so I can then move on to the third. I think it may be a problem with my loop. I realize that this is a complicated task for a beginner to tackle, possibly out of the scope of this forum, but I am also open to suggestions for a better way to accomplish this task.

//Here's my array:
 
var chooseFR = [[["California"],
			["Alfalfa","Insecticide","Fungicide"],
			["Asparagus", "Miticide", "Herbicide"],
			["Berries", "Fungicide","Miticide"]]				
		[["Arizona"],
			["Citrus","Insecticide", "Herbicide"],
			["Cole Crops", "PGR", "Herbicide"]]];
 
//I use this to populate the first dropdown at initialization, which works fine
 
function getState(dropdownField)
{
   dropdownField.clearItems();
 
   for (var i=0; i < chooseFR.length; i++)
 
      dropdownField.addItem(chooseFR[i][0][0]);
}
 
//I am trying to use this to populate the second dropdown, but I get 3 
//instances of "Empty" for California 
//and two instances of "Empty" for Arizona in my second dropdown
 
function getCrop(cropField, dropdownField)
{                                              
   dropdownField.clearItems(); 				
   for (var i=0; i < chooseFR.length; i++) 			
      if(chooseFR[i][0] == cropField.rawValue)
      {
	     for (var j=1; j < chooseFR.length; j++) 	
		 {
		    dropdownField.addItem(chooseFR[i][j]);
	  	 }
	  }
}
 
// Here is my change event for the first dropdown
function getStatesOther(myXfa, dropdownField) 
{                                              
   dropdownField.clearItems();					
   for (var i=0; i < chooseFR.length; i++)			
      if(chooseFR[i][0] == myXfa.event.newText)		
	  {                                            		
	     for (var j=1; j < chooseFR[i].length; j++) 	
		 {
		    dropdownField.addItem(chooseFR[i][j]);
 		 }
	  }
}

Sorry for the length, and thanks in advance for any help.

Shellee

My Product Information:
LiveCycle Designer, Windows
thomp
Expert
Registered: Feb 15 2006
Posts: 4411
Yes, you are making this a bit more difficult than it needs to be, for example, putting the state names in an array, but you are on the right track.

For a better strategy, read both parts of this article, it covers almost exactly what you want to do:

http://www.acrobatusers.com/tutorials/2007/js_list_combo_livecycle/

Thom Parker
The source for PDF Scripting Info
www.pdfscripting.com
Very Important - How to Debug Your Script

smartin
Registered: Mar 3 2008
Posts: 5
When I first tackled this problem, I experimented with your form from the Javascript corner, thinking I could adapt it.

Where you have the item prices, I have put the list of items I need in my last dropdown, but I can't figure out how to populate that last field with those items. I tried to use a for loop with addItem similar to that used in the function that sets the part entries in your form, but it hasn't worked.

The three dropdowns are truly dependent on one another (that's why I think the state needs to be in the array) , different crops are available for different states, and for a given state/crop combo there are differing choices for the report.
thomp
Expert
Registered: Feb 15 2006
Posts: 4411
One of the reasons you're having problems populating the dropdowns is the you have a 3 dimensional array, but in the loop for populating the crop list you only access two dimensions. This is futher complicated by putting the states and the same array as the crop and chemical arrays.

Here is a way you can organize your data so that it is easy to use for dynamically populating a combobox.

var chooseFR = {"California":{
"Alfalfa":["Insecticide","Fungicide"],
"Asparagus":["Miticide", "Herbicide"],
"Berries":["Fungicide","Miticide"]
},
"Arizona":{
"Citrus": ["Insecticide", "Herbicide"],
"Cole Crops": [ "PGR", "Herbicide"]
}
};


The Object notation organizes all the different parts in the way that they are realated to one another. You could also use two lists to break the dependancy between the states and the chemicals, just like in a relational database.


For example, the loop to populate the state list looks like this

for(var st in chooseFR )
dropdownField.addItem(st);

The loop for populating the crop list based on the state looks like this

fucntion FillCrop(cState, dropDwn)
{
dropDwn.clearItems();
var crpList = chooseFR[cState];
for( var cp in crpList)
dropDwn.addItem(cp);
}

One other small inefficiency in your code is the use of the "myXFA" variable. the "xfa" node is global and does not need to be passed into a document function.

Thom Parker
The source for PDF Scripting Info
www.pdfscripting.com
Very Important - How to Debug Your Script

smartin
Registered: Mar 3 2008
Posts: 5
Brief background on this form- it is intended to ensure our salespeople don't sell a report we don't offer, thus all of the combinations. For example, for CA we offer three reports for alfalfa, but only two for AZ, and I don't want the report dropdown for AZ > alfalfa to contain the third report that is available in CA.I've been thinking of a way to break the states away from the rest of the information, and I think I can, if I have one array variable for the states, and another for the crop/report combos. Say that the first index of the array is for the crop, and the second is for the report

var CropRept = new Array(new Array(), new Array(), new Array());
CropRept [0][0] = "";
CropRept [0][1] = "";
CropRept [1][0] = "Alfalfa";//begin CA
CropRept [1][1] = "Insecticide";
CropRept [1][2] = "Miticide";
CropRept [2][0] = "Citrus";
CropRept [2][1] = "Fungicide";
CropRept [2][2] = "Nematicide";
CropRept [3][0] = "Cotton";//begin AZ
CropRept [3][1] = "Defoliant";
CropRept [3][2] = "Insecticide";
CropRept [4][0] = "Alfalfa";
CropRept [4][1] = "Miticide";
CropRept [4][2] = "Nematicide";

if [1][j] through [2][j] correspond to CA and [3][j] through [4][j] are AZ, can I put a switch case statement in a function that would loop through parts of the array based on the value of the state variable that is selected in the first dropdown? Is that a crazy idea?