One slightly hidden gem in the Spring ’18 Release Notes is the introduction of two new Base Lightning Components—lightning:recordEditForm
and lightning:inputField
. In this blog post you’ll learn how to build your custom Lightning components even faster with these tools. But before we dig into the goodness provided by those components, let’s revisit where we’re coming from.
When we first introduced Lightning, we provided developers with some basic components for entering and displaying fields according to data type. Those components reside in the force
namespace and are force:inputField
and force:outputField
. Why are these components “basic”? Because you as a developer have to take care of things like field-level validation and styling these components to look like Lightning and use the Salesforce Lightning Design System (SLDS).
To address some of these gaps, we started to add Base Lightning Components to the mix. These components, which are in the lightning
namespace, automatically inherit the CSS rules of the Salesforce Lightning Design System (SLDS). They include, for example, automated input validation capabilities that can be configured via markup. With these new components, it’s possible to create and maintain Lightning applications much faster than with components from the force
namespace. Of course, you were still responsible for calling an Apex controller and handling the consumption of the data.
We addressed the aforementioned requirement of writing Apex by introducing Lightning Data Service (LDS), which went GA with our Winter ’18 release. Using LDS you are able to create, load, save, or delete a record by writing just a couple of lines of markup and a bit of JavaScript. The system automatically takes care of caching and permissions. No Apex needed. Let me repeat: no Apex needed. That also means no Apex tests needed. How cool is that?
But that isn’t still enough…
If you paid attention to the Winter ’18 Release Notes (you did, right?), you likely found the new Base Lightning Component lightning:outputField
. This component is the counterpart of the aforementioned force:outputField
but with a lot more metadata awareness and SLDS styling.
<lightning:recordViewForm recordId="0030Y0000080eMuQAI" objectApiName="Contact"> <div class="slds-box slds-theme_default"> <lightning:outputField fieldName="Name" /> <lightning:outputField fieldName="Phone"/> <lightning:outputField fieldName="Email" /> <lightning:outputField fieldName="Birthdate" /> <lightning:outputField fieldName="LeadSource" /> </div> </lightning:recordViewForm>
By just passing a record ID and the sObject API name as parameter values to the enclosing, lightning:recordViewForm
tag, lightning:outputField
automatically takes care of formatting the field values, displaying the field labels and so forth based on their sObject definitions.
And now with Spring ’18, we’re introducing lightning:recordEditForm
and lightning:inputField
.
<lightning:recordEditForm recordId="0030Y0000080eMuQAI" objectApiName="Contact"> <div class="slds-box slds-theme_default"> <lightning:messages /> <lightning:inputField fieldName="Name" /> <lightning:inputField fieldName="Phone"/> <lightning:inputField fieldName="Email" /> <lightning:inputField fieldName="Birthdate" /> <lightning:inputField fieldName="LeadSource" /> <lightning:button class="slds-m-top_small" variant="brand" type="submit" name="update" label="Update" /> </div> </lightning:recordEditForm>
Code explanation:
lightning:recordViewForm
we’re using lightning:recordEditForm
as the encapsulating tag. This tag tells the system that editable content should be handled.<lightning:messages />
. However, you don’t have to define those messages, as the framework automatically takes care of that based on the sObject definition!fieldName
parameter for every lightning:inputField
and voilà—you get your SLDS-styled input field, including validation and label, derived from the field definition on the sObject.lightning:recordEditForm
tag. This automatically updates the the database once pressed. No custom JavaScript and no Apex needed. You hear me? No custom JavaScript and no Apex needed!This example is rather simple, but also shows the power and flexibility of lightning:recordEditForm
and lightning:inputField
. By passing only the record ID and the sObject API name, you no longer have to take care of:
It’s all handled for you. But you may now wonder how you can combine lightning:inputField
and lightning:outputField
. Let’s look at an example that pulls all this power together.
Users often need to update account information and they need to do this while on a variety of record pages. Thanks to the new Base Lightning Components, we can now build a single component to accomplish this, rather than building quick actions for objects just to use the standard Related Record component.
<aura:component implements="flexipage:availableForRecordHome,force:hasRecordId" access="global"> <aura:attribute name="editMode" type="Boolean" default="false" /> <aura:attribute name="sourceRecord" type="Object" /> <aura:attribute name="sourceRecordFields" type="Object" /> <aura:attribute name="error" type="String" /> <force:recordData aura:id="currentRecord" recordId="{!v.recordId}" fields="AccountId" targetRecord="{!v.sourceRecord}" targetFields="{!v.sourceRecordFields}" targetError="{!v.error}" /> <lightning:card > <aura:if isTrue="{!v.editMode}"> <lightning:recordEditForm onload="{!c.handleAccountLoaded}" onsubmit="{!c.handleAccountSubmitted}" onsuccess="{!c.handleAccountSaved}" recordId="{!v.sourceRecordFields.accountId}" objectApiName="Account"> <lightning:messages /> <lightning:inputField fieldName="Phone" /> <lightning:inputField fieldName="Rating" /> <lightning:inputField fieldName="Description" /> <lightning:button variant="brand" type="submit" name="save" label="Save" class="slds-m-top_medium"/> </lightning:recordEditForm> <aura:set attribute="else"> <lightning:recordViewForm recordId="{!v.sourceRecordFields.AccountId}" objectApiName="Account"> <lightning:outputField fieldName="Phone" /> <lightning:outputField fieldName="Rating" /> <lightning:outputField fieldName="Description" /> <lightning:button variant="brand" onclick="{!c.editAccount}" name="edit" label="Edit" class="slds-m-top_medium"/> </lightning:recordViewForm> </aura:set> </aura:if> </lightning:card> </aura:component>
Code explanation:
force:hasRecordId
interface on the component. This automatically adds an aura attribute recordId of type Id to the component.aura:if
for conditional rendering.lightning:recordEditForm
allows to automatically invoke custom JavaScript according to different circumstances, like when data is loaded, submitted, or after it has been saved. These calls are optional.ightning:recordEditForm
automatically handles the save process. In case of any errors <lightning:messages />
will take care of showing them in the UI.Last but not least, it’s important to mention that LDS as well as lightning:inputField
and lightning:outputField
are backed by our new UI API.
We’re investing heavily in making the Lightning development experience easier for you. By reducing the amount of code that needs to be written and focusing on metadata driven forms, you can now build custom Lightning components easier than ever before.
Here are some great resources that you should check out to get started:
You can also find the example shown above in this GitHub repo, so feel free to install it into the Salesforce DX scratch org of your choice.
René Winkelmeyer works as Senior Developer Evangelist at Salesforce. He focuses on enterprise integrations, mobile, and security with the Lightning Platform. You can follow him on Twitter @muenzpraeger.