Our world is made up of relational data. When you order a burger, do you want fries or onion rings? When you buy a car, do you want red, blue, black, silver, or white? When you shop for groceries, do you want paper, plastic, or reusable bags? When you set out on a drive, do you go left, right, or straight ahead?
Choices surround us, and often one choice leads to another set of choices. In many cases, each choice is dependent on the previous choice. (Queue memories of the early computer adventure games!) In Acumatica, users often need choices narrowed down based on previous choices, but also sometimes based on other conditions. If we had to sift through all of the options at once, the end user experience would be very cumbersome. Fortunately, Acumatica provides a couple of relatively simple solutions… Dynamic Lists for drop-down selections and Restrictors for Selectors.
A dynamic list starts as just a simple value/description list. By defining alternate lists, we can update the choices to a predefined set based on certain conditions. Let’s assume that XXMyDAC.MyField is defined as a list containing 3 options. Then under certain conditions, we want only options 1 and 2 to be available, but other conditions for options 1 and 3 to be available. By default, the DAC in this example might use [SelectableValue.List] to specify all possible options. However, under a certain condition, it might need to limit that list to only 2 options specified in SelectableValues1 or SelectableValues2.
By using SetList in the RowSelected event handler, we can substitute in the user’s condition based selection list. In the example below, we define the full list and 2 alternate lists. We also apply the values using SetList based on the condition we specify. By initializing the object listattr of the type containing the list we want to present, we can then substitute in the values and labels for the list as shown below.
Restrictors for Selectors
When the choices are not predefined lists, we must leverage another tool to control the data returned by the selector. Ultimately, this restriction will be appended to the database command used to select data for the selector. By specifying PXSelectorAttribute for a field, we can control the results consistently or dynamically.
In the example above, we simply employ PXRestrictor with a typeof indicating the Where clause to be appended to the SQL statement. In this example, a field called UsrXXMyCondition has been added in the DAC extension INLocationExt. By specifying “here UsrXXCondition is not equal to Condition1” the field’s selector will exclude INLocation records containing that value. Multiple restrictors can be added as needed, and any condition that fails will prevent the record from being included in the results. Therefore, a complex set of restrictions might indicate something like “X not equal Y or my condition is met”. This means that my condition must be met only when X equals Y.
These examples are very basic, but note that they can be deployed with great complexity if necessary. Just remember to start with a basic selection (static lists or database driven selectors) to make sure the basics work first. Then build on one conditional list or PXRestrictor at a time until you achieve your final objective.