Skip to main content

Build a mobile field sales app

· 9 min read

Field sales mobile app

A common use case for Retool Mobile is sales account management, enabling sales representatives in the field to manage accounts and opportunities wherever they are. This tutorial explains how to build a field sales mobile app for users to: browse, filter, and edit opportunities.


This tutorial demonstrates a real-world use case of Retool Mobile and uses sample data from a PostgreSQL database. Retool Cloud organizations include Retool Database, which you can use to upload and manage sample data.

Before you begin, download the provided sample data in CSV format. Each CSV file corresponds to a database table.

TableDescriptionDownload CSV
field_sales_opportunitiesSales opportunities.Download
field_sales_contactsContacts for each sales opportunity.Download

Import the CSVs to Retool Database using the provided names. Once complete, you can use the same queries and resource used by this tutorial.

Field sales opportunities tables in Retool Database

Much of what this tutorial covers can apply to other resources and data types. You can also use your own SQL database that's connected to Retool.

Get started


You can download a JSON export of this mobile app and import it into Retool.

Once you're ready to begin, sign into Retool and click Create > Mobile app. Set the name to Field Sales.

View and filter opportunities

The first part of the tutorial explains how to look up, filter, and display sales opportunities.

Configure the Opportunities screen

Retool Mobile organizes mobile components into separate screens and creates pathways for your users to follow. Users navigate between screens using the tab bar or by interactions, such as pressing a button or selecting an item from a list.

New Retool Mobile apps initially contain two screens. Select Screen 1 in the Screens section of the mobile panel (left) to display its settings in the Inspector (right panel).

  • The screen's name (screen1) is used internally when you configure settings or write queries. Click on screen1 in the Inspector to edit this and set it to Opportunities.
  • The screen’s title is displayed in at the top of your app and in the tab bar at the bottom, if visible. In the Inspector, set the value for Title to Opportunities.

Configure screen

Retrieve opportunities data

Sales data for this app comes from a PostgreSQL database. You write queries to interact with connected data sources using SQL.

This mobile app uses three queries to retrieve data about opportunities. Click + New in the bottom panel to create a query, select the Retool Database resource, then write the following SQL statement:

select * from field_sales_opportunities order by id;

Save the query as getOpportunities.

Assemble components for the Opportunities screen

You add mobile components to each screen of a mobile app to build the interface by clicking + in the Components section of the left panel. You then configure component properties using the Inspector.

Add the following mobile components to the Opportunities screen, then configure their respective settings:

  • Text Input
    • Name: opportunitiesSearchInput
    • Placeholder: Search opportunities...
  • List Collection
    • Name: opportunitiesCollection
    • Data source: getOpportunities

The Text Input mobile component is used to search for opportunities. Update the getOpportunities query to reference this new input field's value:

SELECT * FROM field_sales_opportunities
WHERE company ILIKE {{"%" + textInput1.value + "%"}}

Final version of the query

The List Collection component automatically configures list options by dynamically mapping values from the query data. Use the Mapped options settings to configure what values to use by referencing item. For instance, setting Title to {{ }} displays each item name as the list option's title.

Title{{ item.type }}
BodyARR: {{('$' + numbro(item.amount).format({thousandSeparated: true})) }}
Source{{ item.image_url }}

The Body field displays a dollar amount that's formatted using Numbro.js, a JavaScript library that's automatically available in Retool apps.

Configure mapped options

View selected opportunity details

This part of the tutorial explains how to display details of a selected opportunity. This involves getting details of the selected item and populating components in a screen with the details.

Configure the Opportunity Details screen

Add an opportunityDetails screen with a Title of Opportunity Details.

Configure screen

Assemble components for the Opportunity Details screen

When an opportunity is selected in the list, its data is available at the List Collection component's selectedItem. The components in this details screen use this information to display relevant details.

First, add an Image component to the Opportunity Details screen with and set the Source value to {{ OpportunitiesCollection.selectedItem.image_url }}. This displays the image of the selected opportunity.

Next, add a Key Value component and set its data to {{ opportunitesCollection.selectedItem }}. This component displays all key-value pairs for the selected opportunity.

As before, use the Mapped options settings to configure what values to use by referencing item.

Display selected opportunity details

You configure event handlers to perform actions in response to certain events. In this case, selecting an opportunity in the Opportunities screen will open the Opportunity Details screen.

Return to the Opportunities screen, select the opportunitiesCollection component, and add an event handler that navigates to the opportunityDetails screen on selection:

  • Event: Press
  • Action: Navigation
  • Method: Navigate to screen
  • Screen: opportunityDetails

Configure event handling

Include associated contact data

Opportunity details should include any associated contact information. Add a new query to retrieve contact data for the selected opportunity:

select * from field_sales_contacts
where opp_id = {{ }}
order by id;

To display relevant contacts, add a Card Collection component to the Opportunity Details screen, set its name to opportunityDetailsContactsCollection, then set the Data source to getOpportunityContacts.

Since there can be multiple contacts for an opportunity, you can configure Card Collection to scroll horizontally with smaller thumbnails and save space. In the Data layout section of the Inspector, set Scroll to Horizontal and Size to Half.

Configure mapped options and card layout

Update an existing opportunity

The final part of the tutorial explains how to enable users to edit a selected opportunity and save changes. This uses the same principles previously covered.

Configure the Edit Opportunity screen

Add an editOpportunity screen with a Title of Edit Opportunity.

Configure screen

Assemble components for the Edit Opportunity screen

The Edit Opportunity screen contains a set of input components that initially display values from the selected opportunity using selectedItem. Add the following mobile components to this screen, then configure their respective settings:

  • Text Input (Company name)
    • Name: opportunityEditCompany
    • Default value: {{ }}
  • Number Input (ARR amount)
    • Name: opportunityEditAmount
    • Default value: {{ opportunitiesCollection.selectedItem.amount }}
  • Date Picker (Close date)
    • Name: opportunityEditDate
    • Default value: {{ opportunitiesCollection.selectedItem.close_date }}
  • Select (Opportunity stage)
    • Name: opportunityEditStage
    • Default value: {{ opportunitiesCollection.selectedItem.stage }}
    • Values: ['Discovery', 'Demo', 'POC', 'Validating Business Case', 'Signature']
    • Labels: {{ self.values }}
    • Label: Stage
  • Select (Probability of closing)
    • Name: opportunityEditProbability
    • Default value: {{ opportunitiesCollection.selectedItem.probability }}
    • Values: [0,10,20,30,40,50,60,70,80,90,100]
    • Labels: ['0%','10%','20%','30%','40%','50%','60%','70%','80%','90%','100%']
  • Button
  • Name: opportunityEditSave
    • Text: Save

The components for this screen

Update the selected opportunity

The final step is to write a query that updates the opportunity with the information entered into this screen, saving those changes back to the database.

Click + New in the bottom panel to create a new query named updateOpportunity, then select GUI mode. This mode uses an interface that makes it easier and safer to write queries that manipulate data.

Queries that make changes to data use Filter by fields to determine which record to update. You can specify a field that contains a unique value, such as an ID, or specify multiple fields on which to filter. This query uses to reference the selected opportunity's ID.

  1. Set Table to field_sales_opportunities.
  2. Change the action type to Update an existing record.
  3. Set Filter by to id = {{ }}

Next, update the Changeset to configure the query with each field name and the input value to use.

company{{ opportunityEditCompany.value }}
amount{{ opportunityEditAmount.value }}
close_date{{ opportunityEditDate.value }}
stage{{ opportunityEditStage.value }}
probability{{ opportunityEditProbability.value }}

Query to update existing opportunity data

Finally, add two Success event handlers to the query that:

  • Trigger the getOpportunities query to refresh opportunity data so it reflects the changes.
  • Navigate back to the Opportunity Details screen

Click Save to save this query.

Add a button to edit opportunity details

The final step is to include an action button when viewing an opportunity so that users can make changes.

Select the opportunityDetailsScreen screen, then add a Right action button from the Actions section of the Inspector:

  • Action: Navigation
  • Method: Navigate to screen
  • Screen: editOpportunityScreen

Configure action button

Wrap up

You have now built a field sales app that enables users in the field to read, filter, and update sales opportunities. Each opportunity also includes a list of related contacts.

By applying the lessons learned here and following the same patterns, you could extend the mobile app's functionality with features like managing accounts or performing common actions like notifying contacts.