Tag Archives: Lightning

Flows in Lightning Experience

Today I want to share some interesting “Flow Nuggets” I learned recently about using Flows within Lightning Experience.

Flows Are Usable In Lightning Experience

First, you can embed Flows onto Lightning pages using the Flow standard component which is currently in Beta. The Flow component can use Flows whose type is “Flow” aka Flows that have screens in them.

This allows for interesting use cases such as creating a wizard with a Flow on a stand-alone Lightning page. For example, perhaps you want to create a commission calculator wizard.

Note: They are also styled using Lightning so they look and feel like they belong in Lightning. Previously, they were, by default, styled as Salesforce Classic even though they could be embedded in Lightning with a Visualforce component and page.

How-To Steps

  1. Create an active flow whose type is “Flow”.
  2. In the Lightning App Builder, edit a page.
  3. Drag the Flow standard component onto the page and select the Flow to use.
  4. Configure any input variables as needed.
  5. Save.

Lightning Flows Can Be Record Aware

Lightning can pass the record’s id to your flow component when on a record page. If your flow has an input variable defined whose name is “recordId” and it’s embedded on a record page, Salesforce automatically passes the record’s id into your flow so you can use it.

This opens up other interesting possibilities such as:

  1. Creating Automated Flows When A Record is Opened. Technically, this isn’t supported but this could be a workaround where the flow queries the record first, does some computation(s), and then updates the record or other records.
  2. Since the flow has the record id, it can query any information from that record or related records and use that in a more context-sensitive way. For example, your commission calculator can now be embedded on your opportunity records and calculate your territory specific commission based on the opp’s products, the account executive’s commission rates and other variables.

Note: If you create an Automated Flow that updates the current record’s fields, those fields may not show the updated values because Salesforce doesn’t have a way, currently, to tell other components on the page from flows to refresh other components.

How to Run Flow from Page Button in Lightning Experience

Douglas Ayers Blog Post shows how one can use an Action button to open a Flow in Lightning to do other use cases. His example is another “Automated Flow” but it’s activated by a user instead of automatically when a record is opened.

What other ways have you used Flows in Lightning? What limitations have you come across?

The Lightning Email Grid Component


A colleague put out a challenge to me and another colleague asking us to create a Lightning component that allows someone to select one or more records and then click a button to email an internal Salesforce user one email for each selected record.

The colleague was saying this for fun and was not meant to be taken seriously but this sounded like a fun learning opportunity so here’s my rough cut.

Email Grid Overview


This Lightning component is a generic component that lets one define the records to be retrieved and the Salesforce email template used to email a specified user one email per selected record. The component’s configuration is specified at design time when it’s added to a page via attributes.


  • Highly configurable to allow someone to specify which fields to display from any queryable object that’s user accessible.
  • Easily reused in different places by using different parameters.


  • This is a proof-of-concept component and is bare bones. It doesn’t have the bells and whistles of a production grade component like paging, searching, filtering, sorting, or better styling.
  • It uses standard Salesforce emailing capabilities to email a specific Salesforce user using email templates.
  • Use only for a reasonable number of records say 100 or less.
  • Success and Error Messaging needs to be added.

Component Markup

The component uses the “EmailGridController” apex class for retrieving its records and emailing the specified individual using the selected records. It invokes the component controller’s init method to query the desired records. The records are then rendered dynamically using the table markup given. The table styling came from the Lightning Design System Data Table Styling Guide.


  • objectName – The API name of the standard or custom object to query records from. This is bound to from the design attribute.
  • fieldSet – The API name of the fieldset on the specified object that’s used to allow one to specify which fields to show in the table.  This is bound to from the design attribute.
  • whereClause – The where clause to use in the SOQL query so one can easily show the desired records.  This is bound to from the design attribute.
  • emailButtonLabel – The button text to show on the “Email” button.  This is bound to from the design attribute.
  • emailTemplate – The name of the email template to use to email the specified Salesforce user. This allows an admin to use different email templates that they configure.  This is bound to from the design attribute.
  • recipientUserId – The Salesforce record id of the Salesforce user to email.  This is bound to from the design attribute.
  • records – These are the typeless wrapper objects that represent the records queried and each record’s fields. This is used internally by the component.
  • columnNames – The list of column names to show as specified from the fieldset. This is used internally by the component.
  • columnAPINames – Unused at this time. May be useful for future enhancements. This would be used internally by the component.

Design Attributes

The design attributes bind to the component’s attributes with the same name. See the attributes above for more information about usage.

Component Controller

Init Method

The Init method takes the objectName, fieldSet, and whereClause, builds the request parameter object from it, and then invokes the getRecords apex method asynchronously. On success, the records aand column names are bound to the component’s records, columnNames, and columnAPINames attributes for rendering the records in the component.

doEmailRecords Method

The doEmailRecords method identifies the selected records, if any, and builds an email request to invoke the emailRecords function on the apex controller to email the specified user one email for each selected record using the email template specified.

Note the use of JSON.stringify to build a JSON string for the request parameter object. The framework isn’t smart enough to deserialize the request object into its corresponding Apex Request object so it has to be passed in its JSON string representation and then manually deserialized server side.

Apex EmailGridController Class

getRecords Function

The getRecords function takes in a RecordsRequest parameter that is used to dynamically query Salesforce records and return them using a list of typeless records using a record wrapper.

Debug statements were intentionally left in to make troubleshooting easier.

emailRecords Function

The emailRecords function emails the specified Salesforce user one email for each Salesforce record selected using the email template chosen. The records, emailtemplate and id of the user to email are located in the EmailRecordsRequest.

There’s pending work to pass the email results back in the response.

Record Subclass

This class is a wrapper class that represents a row in the table in the component. The Record property isn’t actually used at this time because the Lightning component framework doesn’t allow subscripting into it dynamically like you could with Visualforce. To get around that, a simple list<String> contains the values for each field on the record. Since the order of them corresponds to the order of the column names, they’re easily traversed using the Aura:Iterator to show the record’s values.

Other Thoughts

  • The component can be genericized further to allow one to specify any desired action to be done with a set of selected records after clicking the button.
  • The formatting of dates and datetimes may look undesirable in the table since String.valueOf is being used to convert the value to an SObject field value to a string.
  • It took about 5 hours to get this basic sample working. The two main challenges were 1) trying to figure out why my object requests weren’t invoking the server side functions and that’s because the Lightning component framework doesn’t support automatically serializing and deserializing complex parameter types. 2) Figuring out how to dynamically show the columns and their values since the Lightning component framework doesn’t support direct SObject field access like Visualforce does at this time.

What did you think of this solution? What other features would you implement? How did you implement generating a dynamic list of records and columns to be shown in a component?

The Lightning Lookup Dropdown Component



In Lightning Experience, a textbox is rendered for lookup and master-detail fields. After you start typing in a few characters, Salesforce starts showing matching records in an autocomplete list. This assumes you know which parent record you’re looking for. If the parent object has a manageable number of records, say 200 or less, it would be better to have a dropdown list of all the choices.

Solution: Lookup Dropdown  Lightning Component

This new “Lookup Dropdown” Lightning component is a generic, record detail custom component. An admin drags it onto a record detail page, configures the “Lookup Field” to use and the button label, and the component will automatically determine what the parent object is, query all the records in it and dynamically generate a dropdown list with all the queried records with each item showing the record’s name for the label and its Salesforce record Id as the value. When someone clicks the button, the lookup or master-detail field of the given record is updated with the chosen dropdown value.

Component Markup

The component starts with two main attributes:

Controller: This defines the LookupDropdownController Apex class that it will interact with for getting the various parent records and saving the lookup or master-detail value back to the database in Salesforce.  The internals of this Apex class will be shown later.

implements: This defines which interfaces the component implements and the behavior it supports. In this instance, the flexipage:availableForRecordHome interface tells us that this component can be shown on record detail pages, the force:hasRecordId interface instructs the Lightning component framework to give the component the current record id this component is on via the “RecordId” attribute that is automatically inherited, and the force:hasSObjectName interface gives the component the SObject name of the record that this component is on in the sObjectName attribute that is automatically inherited.

The attribute elements describe the “variables” that can be used in the javascript component controller or bound to via the component’s designer attributes. The two primary attributes are the lookupField and the submitButtonLabel. The lookupField is the API name of the lookup or master-detail on the current record that should have its parent object’s records queried and dynamically generated into the dropdown list. This is done at design time when editing the page layout. The submitButtonLabel describes the text to show on the button and its default value is “Update”. This is also configurable at design time when editing the page layout.

The aura:handler elements are events that the component registers for. The “init” event says to invoke “initLookupDropdown” component controller method when the component is first initialized. The “force:refreshView” event is invoked when the page that this component is on is refreshed and it instructs the component to invoke its “initLookupDropdown” method again. It does this so that if the lookup field is updated elsewhere on the page, the component will automatically update itself to show the latest value.

The aura:If block is there for diagnostic purposes and is hidden by default. If someone selects “Yes” for debugEnabled, the components attributes are outputted so one can more easily debug the issue.

The lightning:select element is a Lightning base component that renders as a dropdown list. Its values and label are dynamically updated when the component is initialized when the page opens.

The lightning:button saves the chosen dropdown value back to Salesforce by invoking the “saveLookupValue” function on the component’s controller.

Design Attributes

The designer file lets one declare which attributes at design time are bound to the component and drive various behavior. This component has three configurable options:

lookupField: Lets one give the API name of the lookup or master-detail of the record this component is on.

submitButtonLabel: The label to display on the “Save” button of this component. The default value is “Submit” but can be overridden.

debugEnabled: This “Yes” or “No” dropdown list allows one to show additional diagnostic information when “Yes” is selected. This defaults to “No”.

Component Controller

The component controller is comprised of Javascript methods and functions that update the component’s view and interact with a Salesforce controller if needed to do various operations. This controller has two functions:


This function invokes the apex controller’s “loadLookupDropdown” function and passes it the sObjectName, lookupField, and recordId. It passes back the selectableRecords that are then dynamically bound to the dropdown list and sets the dropdown list’s label.


This function invoke’s the apex controller’s “saveLookup” function to save the selected dropdown list value to the given lookup or master-detail field on the current record. If the call is successful, the force:refreshView event is fired so that all the components on the page are refreshed. This is necessary in case this field is shown on any other components on the page and its value is updated to reflect the new value.

As you can tell from the javascript, an asynchronous AJAX call is being invoked and then a callback function is used to process the response of the service invocation.

LookupDropdownController Apex Controller

In order for a method or function on an apex class to be invocable from a Lightning component’s controller, it must be static and decorated with the @auraEnabled attribute. The controller has two primary functions:


This function takes in the objectName, lookupField, and recordId and dynamically determines the lookupField’s label to show, dynamically queries all the records on the parent object, and gets the lookup value of the current value on the record. This information is passed back to the component to dynamically build the dropdown list.


This function saves the selected lookup value in the dropdown back to the given record.


  • This component can be used on any record of any object.
  • It can be placed anywhere on the record’s page layout.


  • This shouldn’t be used for a parent object that has say more than two hundred records in it. Searching through too many records would be burdensome.
  • Only the name is shown on the dropdown list’s items.
  • This took about 8 hours to develop and more coding than I was expecting so be mindful of how long a component may take to implement.

What was your first Lightning component development experience like?


Lightning Experience Review: A Few Weeks In

The last few weeks were spent learning and being hands-on with Lightning Experience, which is Salesforce’s replacement UI for internal, non-community users.  Here are my thoughts on it so far.

User Interface


A screen shot of the “All Accounts” listview in Lightning Experience from a personal development org.

Overall, the user interface is better than Salesforce Classic but it  feels like an incremental improvement instead of a revolutionary one.

Salesforce decided to keep feature parity with Salesforce Classic and make the look and feel modern using a Single Page Application (SPA) architecture using individual components built on the Aura framework and the Lightning Design System. The structure of the pages consist of

  • Global Search – The global search is at the top so one can search for records and files.
  • App Switcher. The App Switcher displays the currently selected application, which is the “Sales” application in the above screen shot. The application is the list of tabs that comprise that application which can be customized like in Salesforce Classic.
  • Navigation Bar – The navigation bar is the collection of tabs in the application. All the Object Tabs are a menu that let you, depending on permissions, create a new record, view recently viewed records, and view recent viewed listviews.
  • Main Body – This is where the main content is displayed. In the above example, the all accounts listview is displayed.

Having used Salesforce Classic for years, it was very easy to pickup the basic interactions since most of the day-to-day operations had a one-to-one comparison to Salesforce Classic features and concepts such as Objects, Listviews, Search, and navigation. It also works well on mobile browsers compared to Salesforce Classic.

Sluggish Performance

Everyone keeps touting that Lightning Experience is faster because it uses a SPA architecture with its client side framework, Aura, but it feels slower to me than Salesforce classic. When initially logging in, it takes around 3-4 seconds to open the vanilla dev org’s home page. Salesforce Classic opens the home page within a second. A quick search yields the Lightning Experience LEX – lightning speed please! Idea.

Many factors affect performance so try this out in your own sandbox and see what the performance is like. I’m comparing Lightning Experience performance in my own personal development org with a few thousand test account records to Salesforce Classic on the same org using a 2016 mid-grade laptop on a broadband connection.

Too Much Asynchronous Behavior

After the initial page loads, the processing image is often seen when opening menus on the tabs and other areas that you wouldn’t expect since you just waited a decent while for the application to open.

Administration Awkwardness

Record Page Layout Admin with VF

The main “Details” tab and the “Related” tabs are configured using page layouts from Salesforce Classic. When you can drag-n-drop various components onto the page and rearrange them with ease but then have to view the page layout in Salesforce classic to affect the details and related lists, it is awkward and feels unpolished.

From a technical perspective, it makes sense to use the same page layout configuration to drive both the Salesforce Classic and Lightning Experience record page layouts so they have a similar look and feel for when someone switches between the views and it reduces how much configuration is needed for the UIs. However, the administration experience is still awkward. I want a Lightning experience page editor that’s completely done within Lightning and doesn’t depend on Salesforce classic page layouts. Understandably, this would cause more work for an admin if they have to keep the layouts synchronized between Lightning Experience and Salesforce Classic but it also gives the ability, more easily, to allow different page configurations across the user interfaces.

Visualforce setup pages show in Lightning


Instead of creating Lightning Experience specific administration pages, Salesforce decided to reuse many of its existing Salesforce Classic administration pages but within the Lightning Experience “container”. See the global picklist value sets image above for an example.

Object Definition Custom Field Paging

When viewing an Object’s definition in Object Manager, the list of fields are paged now to show 25 fields at a time. If you’re viewing an object with a lot of fields, say 100 or more, you have to scroll through the pages or use the object’s search to find the desired field(s). This is one area where I actually preferred seeing all the custom fields without having to page through them. These extra clicks mean extra time to examine an object and find the details desired. It would be nice to have an option to view all fields and be able to keep that preference enabled.

Lightning Component AppExchange

Salesforce has a new Lightning Component AppExchange marketplace where ISVs can sell Lightning components. This is great in theory but at the time of this writing, early Feb 2017, there are only about 90 components. Many of them seem useful but none feel compelling enough to be a must-have. Since the marketplace has been around for a while, I was expecting hundreds of components to be available instead of 90. This seems to be an indicator that Lightning still isn’t mainstream and has a ways to go yet.

What’s nice is that ISVs can upgrade their existing AppExchange packages or develop new ones to be Lightning compatible. On the AppExchange, the products that are Lightning ready have the “LIGHTNING READY” designation in their listing as seen below.


Lightning Development

A separate post or two will be created in the future to detail this more.

So far, I’ve developed a generic Lightning “Lookup Dropdown” record component that lets one drop the component on a record detail page, tell it which lookup or master-detail field to use, and it’ll show a dropdown of all the records in the parent object. One simply chooses the parent record and clicks Update to update that field with the selected record.


The use case for this is to replace the out-of-the-box Lookup textbox field that uses autocomplete after typing in a few characters to find the desired parent record. If the parent object only has a manageable amount of records, say 200 or less, show all of them so the user doesn’t have to know which one to select.

To develop this fairly simple component required more Javascript and Apex than expected. To implement the same functionality with a Visualforce component would’ve taken half the amount of code. What led to this is that the Lightning Component Framework doesn’t handle as much of the plumbing for you, at least yet, as compared to Visualforce. Also, the list of available Lightning components is still limited. I’m expecting Salesforce to release more infrastructure and components here to ease the burden on Lightning development in future releases.

Limited “Lightning” Community Support

Lightning Experience is not supported in communities at this time.

What is supported are a few “Lightning” compatible templates. These include the “Napili”, “Koa” and “Kokua” templates at the time of this writing in early Feb 2017. Future posts will detail my experience with these. For now, I recommend starting with the Napili template and evaluating if that’s a good fit for your community.

Closing Thoughts

Lightning Experience at first glance looks impressive but after using it for a while, it still feels like a Beta to me that needs a bit more polish and performance tuning. My recommendation is to use it for out-of-the-box implementations that require little to no customization and wait a few more releases for Salesforce to implement more Lightning features and infrastructure and then reassess.

What are your thoughts on Lightning Experience? Has your team and organization switched over yet?

Gaps Between Lightning & Salesforce Classic

This is the first post in a series of Salesforce Lightning posts. New posts will be created as I navigate the SF Lightning Learning Curve.

What is Lightning?

Lightning is Salesforce’s new User Interface (UI) that replaces Salesforce classic. It’s a framework of client-side, Javascript components that let one build a responsive, modern interface. See Lightning FAQs for more details.

Gaps Between Lightning & Salesforce Classic

Salesforce has been hard at work for about 2 years now enhancing Lightning so that it has the features that Salesforce Classic has. However, there are still gaps between the two and Lightning is even able to do do things Salesforce Classic never could. Here’s a list of things that will likely impact you.

Disclaimer: This is not a complete list.

Regular User Gaps

  • Lightning does not allow customizable dashboards.
  • Lightning does not allow customizable home page components.
  • Lightning doesn’t support Account teams, Account and Contact hierarchy, or person accounts.
  • Lightning doesn’t support merging Accounts, Contacts, or Leads.
  • Lightning doesn’t support Joined Reports, Details of Matrix Reports, Tables Funnel and Scatter chart types, and scheduling of report refreshes.
  • For Listviews, Lightning doesn’t support resizable columns or Advanced filter logic. However, it does support charts and creating filters on the fly, which Classic does not support.

Admin Gaps

  • Can’t apply custom branding, including custom logos or colors, to the new interface.
  • Custom buttons that use a URL or Javascript content aren’t supported. Some of this functionality can be replaced with Process Builder, Visual Workflow, or custom code.
  • Custom links with parameters for filling in form fields aren’t supported.
  • You can’t define custom field-level help or add field-level help for fields in custom objects.
  • Field sets aren’t available in Lightning Experience. If you or someone in your organization created a field set while using Salesforce Classic, you see the global variable for field sets in places such as formula fields and Visualforce pages, but you can’t manage them in Lightning.
  • Apex Sharing Rules not available.
  • Apex Sharing Recalculations not available.

Setup Gaps

The Lightning Setup experience doesn’t provide all the functionality that Classic does.

  • An org’s edition information isn’t visible.
  • Advanced currency management, or dated exchange rates, isn’t supported in general.
  • Languages that are read right-to-left, including Arabic, and Hebrew, aren’t supported. All other locales and languages are supported.
  • The Setup Tree is limited to Pages that support Lightning and Admin pages that apply across your org.
  • Advanced setup search isn’t available.
  • To access other setup pages, Classic setup must be used.

Programmatic Gaps

  • Lightning Page tabs and custom Lightning Pages are currently available for the Salesforce1 mobile app only, and aren’t available in Lightning Experience.
  • Visualforce – This release a beta version of Visualforce for Lightning Experience that is production quality but with known limitations. Here are some of the important ones:
    • Visualforce is Wrapped in an IFrame in Lightning Experience.
    • sforce.one No longer Used Only in Salesforce1.
    • You can’t set window.location in Javascript.
    • Lightning Experience App User Interface is always visible.
    • Page Title can’t be set.
    • Home Doesn’t Support Visualforce.
    • Navigation Menu Doesn’t Support Visualforce.

Navigation Gaps

  • Navigation Menu Replaces the Tab Bar.
  • Apps and Custom Objects Available from the App Launcher Only
  • Open links in New Browser Windows or Tabs generally supports except in the following areas:
    • Links in the Top Deals and Recent Records cards on Home.
    • Action icons, buttons, and menu items on records.
    • Links To Notes.
    • View Report links on Dashboards.
    • Links on the Lightning Experience Setup page.

Action Gaps

These actions and buttons aren’t available in Lightning.

  • Deep Clone.
  • Mass Delete.
  • Mass actions on home pages and list views.
  • Data import tools on object home pages.
  • Sharing buttons.
  • Custom buttons that define the content source as URL or OnClick Javascript.
  • Custom links with parameters for filling in form fields.

AppExchange Apps

Some apps on the AppExchange support Lightning. If an app is supported, a “Lightning Ready” sash appears on its AppExchange Listing. If an app isn’t supported, use Salesforce Class instead.

Packaging and ISVForce Gaps

  • These packaging features aren’t supported in Lightning:
    • Creating a package.
    • Uploading a package.
    • Upgrading a package.
    • Deprecating a package.
    • Creating a branch or patch organization.
  • These ISVforce features aren’t supported in Lightning:
    • Channel Order App
    • Environment Hub
    • Trialforce
    • Usage Metrics Visualization App

Mitigation Strategies

  • Continue using Salesforce Classic until Lightning is enhanced to have your desired features. Salesforce provides 3 major releases per year, roughly every 4 months, and each release usually has more Lightning features.
  • Build your own Lightning Components to support the functionality desired. With Lightning being a framework that is customizable, you can build any desired functionality. Do your Cost-Benefit analysis to see if this is worthwhile. You could potentially sell your components on the Lightning AppExchange to offset your costs
  • Lightning AppExchange. See if there are Lightning components on the Lightning AppExchange that will provide the desired functionality for you.