The Lightning Lookup Dropdown Component

Lightning_Lookup_Dropdown

Problem

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:

initLookupDropdown

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.

saveLookupValue

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:

loadLookupDropdown

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.

saveLookup

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

Benefits

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

Considerations

  • 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

Lightning_Accounts_Example

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

Lightning_Global_Picklist_Admin

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_Ready_AppExchange

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.

Lightning_Lookup_Dropdown

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?