Cascading Dropdown

908
3
12-04-2013 06:45 AM
BenFriedrich
New Contributor
Im still fairly new to pyhton scripting in Arcmap and the whole scripting process.
I have made a scripting tool that is made to help the user to navigate to an address on a map. what i need to do though is make it easier by settign up the parameters in a neater way. Right now the way its set is it is the paramters are drop down list of all possible options but i want to set it up so that if i choos from parameter 1 a certain street name, in parameter 2 it will only give me street types that match with that street name.
Tags (2)
0 Kudos
3 Replies
MattSayler
Occasional Contributor II
Are you doing this through a normal script tool (like in a toolbox) or through an add-in tool?

In the first case, you could modify the validation code (right-click the script tool, properties, validation tab) so that when the first parameter is altered, you use the value to filter the list of the next parameter.
http://resources.arcgis.com/en/help/main/10.1/index.html#//00150000002m000000

Example of some validation code I modified. Have to fill in the first parameter, database connection, first (everything else is disabled). Once it's been entered, the connection is used to path to a feature class and derive a picklist from one of its fields. The script then enables the other parameters.

 #-------------------------------------------------------
 # BufferFeeder.py validation code
 # Feb 2012 msayler
 # Updated Jul 2012
 # Must be copied into the script tool's validation code 
 # in the Validation tab under Properties
 #-------------------------------------------------------
class ToolValidator:
 """Class for validating a tool's parameter values and controlling
 the behavior of the tool's dialog."""

 def __init__(self):
  """Setup the Geoprocessor and the list of tool parameters."""
  import arcpy
  self.params = arcpy.GetParameterInfo()
  self.X = 0
  self.fcfield = (None,None)

 def initializeParameters(self):
  """Refine the properties of a tool's parameters.  This method is
  called when the tool is opened."""
  self.params[1].enabled = False
  self.params[2].enabled = False
  #self.params[3].Value = self.X #for debugging
  return

 def updateParameters(self):
  """Modify the values and properties of parameters before internal
  validation is performed.  This method is called whenever a parameter
  has been changed."""
  
  if self.X == 0:
   if self.params[0].altered == True:
    FC = str(self.params[0].value) + "\\gis2.ELEC.ElectricDataset\\gis2.ELEC.eCircuitBreaker"
    Col = "FeederID"
    self.fcfield = (FC, Col)
    self.params[1].filter.list = [str(val) for val in \
            sorted(\
             set(\
              row.getValue(Col) for row in \
               arcpy.SearchCursor(FC, None, None, Col)\
             )\
            )\
           ]
    self.params[1].enabled = True
    self.params[2].enabled = True
    self.X = 1
   #self.params[3].value = self.X #for debugging
   
  # if self.params[1].Value not in self.params[1].filter.list:
   # self.params[1].Value = self.params[1].filter.list[0]
  return

 def updateMessages(self):
  """Modify the messages created by internal validation for each tool
  parameter.  This method is called after internal validation."""
  return


For the second case, I haven't worked with add-ins yet, but I think you could do a similar sort of process. Catch that the field has changed, then use the value it changed to to calculate the choices for the next one.
0 Kudos
DouglasSands
Occasional Contributor II
What you are talking about is definitely possible with a tool validator. How you would go about it depends on if you have written the tool as a script that you reference in a toolbox (.py extension) or as a python toolbox (.pyt extension).

In a .pyt toolbox I use the following to make sure that two parameters never reference the same field:

def updateParameters(self, parameters):
    '''Modify the values and properties of parameters before internal
    validation is performed.  This method is called whenever a parameter
    has been changed.'''
    #Need to make sure that the additional fields option ONLY lists fields
    #that will not be standardized.
    if parameters[0].value:
        old_fields = [field.name for field in arcpy.ListFields(parameters[0].value)]
        if parameters[1].altered:
            if parameters[1].valueAsText in old_fields:
                old_fields.pop(old_fields.index(parameters[1].valueAsText))
        if parameters[2].altered:
            if parameters[2].valueAsText in old_fields:
                old_fields.pop(old_fields.index(parameters[2].valueAsText))
        parameters[3].filter.list = old_fields


The syntax would be similar to this in the tool validator if you are using a .py file. There is some more discussion in this thread about using tool validators.

Hope this helps,
- Doug
0 Kudos
BenFriedrich
New Contributor
OK thank you for your help i was able to find the way to properly set it up in the tool Validator
What i needed to end up doing was in the update paramameter
[PHP]
fc=self.params[0].value
col="ST_TYPE"
query = ('"ST_NAME"='+"'"+str(self.params[1].value)+"'")
self.fcfield=(fc,col)
self.params[2].filter.list = [str(val) for val in
                                    sorted(
                                      set(
                                        row.getValue(col) for row in
                                        arcpy.SearchCursor(fc,query,None,col)
                                        )
                                      )
                                    ][/PHP]
0 Kudos