How Do I Build FlexCards? The Thought Process

Learn how to identify which design patterns to use for your FlexCards. This post is part of the FlexCard Design Thinking mini series.

To recognize what patterns you need to follow, do a little self-inflicted discovery and ask yourself the following questions.

First, review the design patterns in this series and come up with a use case.  You will more easily understand what you’re doing if you have your own use case in mind.  This is my #1 tip for learning just about anything, including Flow. Maybe pick something from a recent app build or your existing org that you’re familiar with.


Q: Are you using record data or static content?

Record data = Requires something like a DataRaptor to bring data into the card.

Some reasons you might need record data:

  • Display it to the user;
  • Use it to conditionally show parts of the card (e.g. show text or user instructions based on the case status, hide a button based on the user’s employment status, hide fields when they don’t apply to the case type); or
  • Pass it along to an element on the card (like an action button that opens an OmniScript).

To get to record data, you will create a DataRaptor that pumps that data into the card. There are other options (like Integration Procedures or writing a SOQL query), but DataRaptors are pretty easy. When you configure your card, you tell it which DataRaptor to use as the data source.

Static content / no record data = no DataRaptor needed, very simple.


Q: Are you displaying a single record or a list of records? Does the card need to iterate over multiple records?

Single record… A single card is fine.

List of records… Consider using two cards.

When I have a card that displays multiple records, the entire card will repeat for every record. But usually I want my list to be inside a box or appear with a title above it. If I only use the one card, that box and title will repeat for each record. Yuck.

To achieve the desired affect, I create two cards. My first card is the parent – it displays the title and provides the border box around the list, and then I embed a second card (the child) in the middle of it, so that the records repeat inside the parent. Ahhh, much better.


Q: Does my card need any inputs?

No, my card works without inputs… This is often the case when your card:

  • Only contains static content;
  • Shows records that are common or shared…
    • It will use Salesforce org-wide defaults, sharing rules, and the role hierarchy to control which records users will see; or
    • It will use a DataRaptor that is hardcoded to show the right records (e.g. Get all Cases where Status = Open and Priority = High).

Yes, my card needs to know something about the current record or user… This is true when your card can’t display or or pass along data without knowing context – typically the identity of the current user or record.

You can take advantage of a number of global and local context variables in your card. These provide you basic but powerful data points. The most famous ones are the Three Tenors:  {recordId}{User.userId}, and {User.userAccountId}. O sole mio!

Typically, you will need to feed one of these context variables to your DataRaptor as an input so that it retrieves the desired data. So what does your DataRaptor need? The current page’s recordId? Something about the current user? Don’t overthink it – you usually just need one.

Note: Even a card that displays static content might sometimes need a context variable. The related use case I run into the most is that my pretty, static content card needs to display an action button that opens another card or an OmniScript. I might need to pass along the current recordId for that asset to work properly.

Yes, my card needs to know something from the parent card in which it is embedded… In this case, your card is being embedded in another FlexCard or OmniScript (the parent), and you need to pass something from the parent (a variable, an Id, a field value, or maybe even an entire record) to make your child card work. This might require a slight tweak to your parent card or script.

You pass data to child cards and actions using input parameters.

If all the data you need for the child is located in the parent, you do not need another DataRaptor – you can pass all the data from the parent card to the child.

Child cards have access to some of the same context variables as the parent card (OmniScript not so much). This means you don’t have to worry about passing something like {recordId}{User.userId}, and {userAccountId} to the child – it’s already there.


Q: Will my card need to look dramatically different when empty or when certain conditions apply?

No, I’m just building a simple card of refined beauty and elegant design, jeez… Okay, okay, no problem. Just asking.

Yes, how’d you know? My card should look way different depending on status, or when it returns no data… Not my first rodeo, kid.

You may benefit from using FlexCard states. States are ways of showing different versions of the same card, but each state displays when certain conditions are triggered.

By default, every card comes with one state, the “active” state – this is the version of your card that displays when your data source returns data to display the card (or when you build a static card). When your card has no data, it doesn’t show up at all.

You can create an “empty” state – what the card looks like when your card’s data source returns no data.

You can also create other states so that your card looks differently based on other conditions, like a status field.

Tip: Create the main state of a card first and then clone it to create the other states (this is a huge timesaver).


One thought on “How Do I Build FlexCards? The Thought Process

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: