Dropdown Menus
Introduction
Dropdown lists are a great way to allow a user to pick from a list of items, while keeping the UI elements to a bare minimum.
Create your Dropdown
Start by creating a new Airkit application (or editing an existing one):
- Once your application is open in Studio, go to the Web Page or Container you’d like to add a dropdown to.
- Click on the '+' button on your Web Page or Container to add elements, and select Container / Web Page → Dropdown List :
Now that we have a dropdown, its possible to customize it's styling within Inspector > Style.
Dropdown Customization
There are a lot of ways to style a dropdown which we won't go into full-detail here, but below is a simple example where the Arrow has been made blue with a grey background.
If you're interested in learning more about styling, we recommend looking at our documentation on Themes and Control Variants.
- Let’s dive in! The main properties' sections for a Dropdown list are:
- Control Properties
- Data Binding
Control Properties
In the control properties section you can set up the variable you’ll be saving the selected option to (value) as well as the text shown to the user when no option has been selected (placeholderText).
_variable_to_save.selection_to_
needs to be a valid variable i.e. it needs to exist within your application. If you are not yet sure of the scope you need for your variable, it is ok to use session while you build (not recommended for published apps): session.variable_to_save.selection_to
Please review your variable scope to make sure you’re using the appropriate variable scope.
- Data Binding
In the Data Binding section, you can control the data used to populate the dropdown list and how it’s displayed to the user.
- Data is the List of items that will be shown as a list when opening the dropdown. You can hard-code a List or use a Data Flow to query an App Object and display a List. The above example displays contains a hard-coded List for the Dropdown.
- Display Text is the value that reflects what will displayed. In simple examples, the value should be "item" to reflect each item of the Collection / List provided to the Dropdown.
- Value Text is the value that is saved when the app user selects an item from the Dropdown List.
- Selected gives you the ability to control whether the value selected is displayed to the app user. This field evaluates an expression where if TRUE, will display the value to the app user. For a more-detailed explanation, see Dropdown List Control.
Static and Dynamic Dropdown Lists
Creating a Static Dropdown List
Option Lists are useful when the items in the list are known at the creation time of the app. For example, selecting a lead type for a new salesforce contact or selecting a t-shirt size on an ordering form. Let's build out the example to rate a book in the AirBooks app.
Start with a Web Flow with one page on it. Add a label of the large variant, set the text to "Enter Your Book Review:." Next, add a container with a label and a text input. Set the label equal to "Enter the book title." Add a new container with a label with the text "Select a rating." Next, add a Dropdown list under the picker option in the Add Control dialog.
With the dropdown selected, the inspector will have a section called Data Binding. This section is used to determine the items that will appear in the list and where the selected value will be stored. By default, when a dropdown is inserted into the Tree a variable is created to store the result. There are two options for dropdown list type: simple list, and custom expression. Simple list, also known as an option list, is where you configure the items in the UI.
Add five different items by clicking the + icon to the right of the options. Set the values to 1 Star, 2 Stars, 3 Stars, 4 Stars, and 5 Starts. In a simple list, when the user selects an option from the dropdown, that text value will be stored in the text variable.
Creating a Dynamic Dropdown List
Whereas simple list dropdowns are great for known information, dynamic lists are great for use when the items in the list can be dynamically run generated at run time. These are also useful if the list will be populated from configuration information that may change over time. Let's say that in addition to letting the user rate the book, the user should be allowed to select the category of the book during the review.
Start by going to AirData Builder and creating a new App Object. Title it "Genre", rename the property from Name to genre_title and add options in AirData Builder for the categories: "Youth", "Reference", "NonFiction", and "Mystery." Click save and click continue on the save dialog when it appears. It is simply saying that we are adding new data to the AirData Datastore attached to our app.
Go to Connections Builder and add a new Data Flow named "AD - Get genres." Modify the first Data Operation to be of type "Object-Service." Select the app object Genre from the dropdown. Make sure the type is QUERY. Click Run at the top of the step and confirm that the output contains the shelves you added above. Because the query run returns a complex object with a bunch of different options, add a transform step after the query. Set the body of the transform to:
airData.results[*].genre_title
Return the result of the transform from the Data Flow.
[
"Nonfiction",
"Mystery",
"Reference",
"Youth"
]
Go to Web Flows Builder and modify our book review page to add a container between Star Rating and the Review box. Add a label "Genre" and a dropdown list to the container. Instead of the simple option list, this box will be populated by the connection built above. Select the Web Page and add a variable called genres as a list of text.
With the Web Page still selected, go to the Actions tab in the inspector and add an action for Run Data Flow under the App Section in the Action Inspector Tab. Select AD - Get genres from the dropdown and the output binding to genres.
Select the dropdown list in the shelf container. Under Data Binding look for the Type of List option. Change it from "Simple List" to "Custom Expression." Set the Data value of the expression to genres and the Display Text to item. Run the page in preview and see the example below.
To add another genre to the list, simply go back to the AirData Builder and add another row for the "Science Fiction" genre. Notice how the list will automatically contain the new item.
Selecting multiple items from a list
The dropdown list that has been covered so far is for selecting single items from a list. In the case where multiple items can be selected, using a list of checkboxes might be more appropriate. In the example above, perhaps a book is a Youth Mystery book.
Replacing the dropdown list with a checkbox list will allow for this multiple selections of Genres. Go to the container containing the genre dropdown and remove the dropdown list. Add a Checkbox List from the Add control dialog, it is under the Repeater section. Add a checkbox and a label to the checkbox cell. Select the Checkbox List and set the data to genres. In order to store the selected genres, go to the Page and add a variable typed list of text named selected_genres. On the Checkbox List set the value to selected_genres. Set the text of the label to item.
Preview the app:
When Dropdown lists are desirable
How Dropdowns compare to other list controls
Dropdowns are just one of several list selection controls in Airkit. The other major possibilities include Checkboxes and Radio Lists. Dropdown lists allow the user to select one item from a list of items. Dropdown lists do this in a relatively small amount of screen real estate. The list expands when the user interacts and only shows the selection after. Radio lists have similar behavior of selecting one item from a list, but display all items visually, even once selected. Checkboxes on the other hand display all items visually but allow for multiple items to be selected.
Why should I use a dropdown?
Dropdowns help with screen space. Use a dropdown on a form where there are a bunch of options and the user must select one. Because the dropdown options are only visible when editing the control, if there are too many options a dropdown might not be the best solution. Scrolling through many items, especially on a mobile device, can be challenging for some users.
Dropdown Menus with Complex Data
Configuring a dropdown to select a Salesforce Contact
Salesforce contacts are complex objects. Using some Airscript, it is possible to populate a dropdown list to select a Salesforce contact. See Additional Reference for more information on a mock salesforce contact.
This example assumes a connection to a Salesforce instance with an integration. To configure your Salesforce Instance, check out Creating a Salesforce Lead for information on how to connect a Salesforce integration.
Go to Connections Builder and create a new Data Flow. Name it "SF - Get Contacts". Change the data operation to type "Salesforce." Select the Salesforce Datasource, and select "Find Records" for the operation type. Choose Contact (Contact) for the Object Type. Add several fields, make sure Full Name is included. Run the operation and the step should return data in the format:
{
"success": true,
"result": [
{
"Id": "0034x000007Ro68AAC",
"AccountId": "0014x000009psYGAAY",
"LastName": "Gonzalez",
"FirstName": "Rose",
"Name": "Rose Gonzalez",
"Salutation": "Ms.",
"MailingStreet": "313 Constitution Place\nAustin, TX 78767\nUSA",
...
Because the list of contacts is in the result property of the Salesforce response, create another Data Operation of type Transform. Insert the following snippet into the transform box:
Salesforce.result
This strips the extra return information from Salesforce and just returns the data in the form of a list of results. Return the transform from the Data Flow.
Go to Web Flows Builder and create a new Web Flow. Name it "Corporate Buyers Program." Create a Web page and add a heading label with the text "Corporate Buyer's Club:" Add another label with the text "Select the account point person:" Create a dropdown list from the picker list of controls. Lastly add a submit button. The page should look something like this:
To connect this to the Data Flow, select the Web Page. In the inspector Add a variable contacts of List of Any type. Create a second variable called selected_contact of type Any. With the page still selected, under the Actions tab add a Run Data Flow action to the "Card Updated" event. Set the action the "SF - Get Contacts" data flow and set contacts for the output variable. This will populate the variable at the time the card is first created.
Select the Dropdown List. In the Data Binding section, change the "Value" to a custom expression and enter selected_contact. This will store the currently selected contact with all of the fields. Change "Type of List" to Custom Expression. For Data select contacts. This will use the list returned from the Data Flow. Set the display text to item.Name. This is the text that will display for each item in the dropdown list. For "Value Text", put in item. This will put the entire contact record into selected_contact. For the "Selected" field, insert:
selected_contact.Id = item.Id
This expression will evaluate to true if the item has the same Id as the selected contact's Id. This is more reliable than checking on Name because it is possible to two contacts to have the same name, but not the same Id. The configuration of the dropdown should look like this:
Save, configure the launch trigger and run in Preview. Interaction with your dropdown should be similar to the following:
Note that even though the example is just selecting the contact's name, the actual value of selected_contact is the full Salesforce contact. This means that selected_contact will have all the additional properties selected from the original object.
Working with complex objects and dynamic dropdowns
If a dropdown list becomes too large, it can be difficult for users to find the exact item they are looking for. It can be easier to group items into a category and allow the user to specify the item within that category.
To demonstrate this let's build a simple example of a towing app. This will ask the user for the Make of a car first then display the items within the make.
Go to AirData Builder and add a new AirData App Object named "Car." Give it text properties of "Make", "Year", and "Model." Populate the AirData table with some data. Click save and click "Continue and Save" on the migration dialog.
Go to Connections Builder and create a new Data Flow named "AD - Fetch cars." Select the AirData option from the Data Operation dropdown. Select Car from the "App Object" dropdown. Leave type query, select paginate and run the operation. Add a transform after to return only the results:
objectService.results
Go to Web Flows Builder and create a new Web Flow. Create a new web page and add a label and a dropdown. Set the label to text to "Select Your Vehicle:" Select the web page and add a variable for all_cars with the type List of Car, add another variable selected_car with type Car.
Select the Dropdown List. Change the value of the Data Binding Value to "Custom Expression" and enter selected_car. Set the "Type of List" to Custom Expression. Fill in the values:
Data | Designation |
---|---|
All Data | all_cars |
Display Text | "{{item.make}} {{item.model}} {{item.year}}" |
Value Text | item |
Selected | item.__id = selected_car.__id |
The .__id property is how the AirData table uniquely identifies each row. It is possible to use it here as a unique identifier for each row rather than comparing the make, then model, then the year.
Preview the app. Notice how long the list is with all the options are:
Depending on the list of cars supported, the user could be scrolling for a very long time to find their car. This process can be improved by changing this one dropdown to three separate dropdowns, one for Make, one for Model, and the last for a year.
Create a new Web Flow. Create a new Web Page. Add a container with a label and a dropdown. Set the text of the label to "Select a make:." Select the Web page and add the following variables:
Variable Name | Variable Type |
---|---|
all_cars | List of Car |
selected_make | Text |
selected_model | Text |
selected_car | Car |
Select the Dropdown and set the value to selected_make. Change the "Type Of List" to Custom Expression. Set "Data" equal to:
FROM
car
IN
all_cars
SELECT DISTINCT
car.make
This is using a Query Expression to pull out all the distinct makes from the list of all_cars.
Repeating the step for Model. Create a container with another label and dropdown. Set the text of the label to "Select a Model:." Set the value of the dropdown list to an Expression with the selected_model value. Change the list type to "Custom Expression" and set the Data to:
FROM
car
IN
all_cars
WHERE
car.make = selected_make
SELECT DISTINCT
car.model
Change the "Selected" option to selected_model = item. Because the model can only be used once the make has been selected. With the container selected to the Advanced tab in the inspector and set "Is Visible" to ISNOTEMPTY(selected_make). This will keep the user from selecting a model without having first selected a make.
Create one more container for the year. Add a dropdown and a label. Set the label text equal to "Select a Year:". Change the Dropdown's Data Binding value to selected_car. Set the Data to:
FROM
car
IN
all_cars
WHERE
car.make = selected_make
AND car.model = selected_model
SELECT DISTINCT
car
Set the display text to item.year. Set the value text to item. Set the "Selected" to selected_car.id = item.id. Because this is the final dropdown, the entire car is selected in the selected_car, whereas in the previous examples, only the value was selected. This will allow access to all properties on the car in the rest of the page. The properties on the data section for the Dropdown should look like:
Because the value year is not able to be selected until both the make and model are selected, set the visibility on the container for the year to:
ISNOTEMPTY(
selected_model
)
AND ISNOTEMPTY(
selected_make
)
Now the flow should work as desired:
Additional Reference
Mock Salesforce Contact
Example of a mock Salesforce Contact Record:
{
"attributes": {
"type": "Contact",
"url": "/services/data/v45.0/sobjects/Contact/0035Y00003p12fmQAA"
},
"Id": "0035Y00003p12fmQAA",
"IsDeleted": false,
"MasterRecordId": null,
"AccountId": "0015Y00002cnHiUQAU",
"LastName": "Gonzalez",
"FirstName": "Rose",
"Salutation": "Ms.",
"Name": "Rose Gonzalez",
"OtherStreet": null,
"OtherCity": null,
"OtherState": null,
"OtherPostalCode": null,
"OtherCountry": null,
"OtherLatitude": null,
"OtherLongitude": null,
"OtherGeocodeAccuracy": null,
"OtherAddress": null,
"MailingStreet": "313 Constitution Place\nAustin, TX 78767\nUSA",
"MailingCity": null,
"MailingState": null,
"MailingPostalCode": null,
"MailingCountry": null,
"MailingLatitude": null,
"MailingLongitude": null,
"MailingGeocodeAccuracy": null,
"MailingAddress": {
"city": null,
"country": null,
"geocodeAccuracy": null,
"latitude": null,
"longitude": null,
"postalCode": null,
"state": null,
"street": "313 Constitution Place\nAustin, TX 78767\nUSA"
},
"Phone": "(512) 757-6000",
"Fax": "(512) 757-9000",
"MobilePhone": "(512) 757-9340",
"HomePhone": null,
"OtherPhone": null,
"AssistantPhone": null,
"ReportsToId": null,
"Email": "[email protected]",
"Title": "SVP, Procurement",
"Department": "Procurement",
"AssistantName": null,
"LeadSource": "Trade Show",
"Birthdate": "1969-02-19",
"Description": null,
"OwnerId": "0055Y00000F9t8fQAB",
"CreatedDate": "2021-03-09T17:17:51.000+0000",
"CreatedById": "0055Y00000F9t8fQAB",
"LastModifiedDate": "2021-03-09T17:17:51.000+0000",
"LastModifiedById": "0055Y00000F9t8fQAB",
"SystemModstamp": "2021-03-09T17:17:51.000+0000",
"LastActivityDate": null,
"LastCURequestDate": null,
"LastCUUpdateDate": null,
"LastViewedDate": null,
"LastReferencedDate": null,
"EmailBouncedReason": null,
"EmailBouncedDate": null,
"IsEmailBounced": false,
"PhotoUrl": "/services/images/photo/0035Y00003p12fmQAA",
"Jigsaw": null,
"JigsawContactId": null,
"CleanStatus": "Pending",
"IndividualId": null,
"Level__c": "Primary",
"Languages__c": "English"
}
Updated over 1 year ago