Recently, I created the Lightning Field Set Record Display Component and the Field Set Form V2 Components that are driven by a field set. One limitation is that these controls display the fields vertically in one column which is great for phones and tablets. However, when there’s more screen space, more sophisticated layouts are desired so I wondered if I could use a page layout to configure a record’s layout. Granted, one should use the force:recordView lightning component since it’s native and does that already but I wanted to explore the possibility. Out of that research comes two new lightning prototypes, the Collapsible Section and the Page Layout Record Display.
These components are now available in the Lightning Prototypes Unmanaged Package.
Collapsible Section Lightning Component
One thing that drives me nuts is that the Lightning Design System has many “Components” and the markup to create them but many of them are not included as standard components within the Lightning framework. This means developers all over the world are creating and duplicating their own versions of this when it isn’t necessary. Furthermore, many of the component examples have markup that isn’t even compilable when you try to use it. Try it with an SVG and you’ll see.
Since I was trying to replicate a record’s standard page layout, I wanted to use a collapsible section. The Expandable Section Component gave me the markup but there wasn’t any standard component for it so I decided to create one. Thankfully, it was easier than expected.
Design Overview
I used the Expandable Section Component as a starting place for the markup. Since the SVG isn’t allowed, I used the lightning:buttonStateful component for the down and right images along with the given title. To collapse the section, one clicks the header which removes the “slds-is-open” class from the section div element. To expand it again, one clicks the header and the class is re-added.
Usage
Limitations
- No Animation. When one clicks the header, it doesn’t animate its collapse or expansion like a section on a record page.
- Little Styling. I used the Expandable Section Component styling to be consistent with Lightning. Feel free to style it further as needed.
Markup
Controller
Page Layout Record Display Lightning Component
My goal here was to create a lightning component that displays a read-only record whose layout is governed by a specified page layout. This was actually much easier than I expected. Granted it’s very basic but it was a lot of fun to learn and put some different pieces together. Here’s what I came up with.
A special thanks to Matt Lacey’s Metadata Layouts in Apex & Visualforce Blog Post for supplying the starting apex code.
Design Overview
The component uses the Apex Metadata API to fetch the specified page layout’s metadata and then it uses that to construct the record’s read-only layout. Currently, the Apex Metadata API lets one access page layout metadata and custom metadata. It’s relatively new in the last release or two and am looking forward to more support in the future. The component uses the layout’s sections with each section having columns and with each column having fields. The layout already had the desired structure so it was a simple matter of iterating over it using the lightning:recordViewForm with lightning:outputFields.
Limitations
- Prototype Quality. This was for learning purposes and had a lot of fun implementing it.
- Needs additional styling. For example, the alignment and spacing needs to be better.
- Salesforce requires some fields to remain on a page layout and can’t be removed.
Account Page Example
Let’s use an Account page layout as an example.
Page Layout Record Display Using Account Page Layout
As you can see, it looks decent but isn’t perfect.
Standard Account Page Layout:
Usage
The component expects the recordId and PageLayoutName attributes to be set. The recordId is the Salesforce 15 or 18 alphanumeric id of the desired record to show. If the component is used on a record page, the recordId is automatically populated. The PageLayoutName is the “API Name” of the desired page layout. For example, “Account-Account Layout”.
Markup
Component Controller
Helper
Design
I thought it would be nice to let someone place this anywhere they wanted and then specify the record id and page layout.
Apex Controller
Unfortunately the Metadata.Layout isn’t “AuraEnabled” so the equivalent view model classes were created to marshal the data.
Apex Controller Test Code
The necessary apex test code to package this.
Future Possibilities
Am considering trying to implement a Page Layout Form for fun or apply additional styling and other expected features to the Page Layout Record Display to polish it.
Let me know what you think in the comments below.
Hi Luke! This component is great! Any thoughts on making the Record ID dynamic based on the record of where the component is displayed vs. having it be a static ID?
I found that if I just put ‘force:hasRecordId’ in the record id field in the page layout editor, it automatically pulls in the ID of the record that this component is displayed on. So, I think I answered my own question, but this component is exactly what I need. Until at least SF releases the ‘Lightning – Tabs on Record Detail for Page Layout Sections’ feature they have talked about.
See for reference: https://success.salesforce.com/ideaView?id=0873A000000CQ30QAG
Hey Holly,
Glad it helped and thanks for the feedback!
Hi Luke,
Do you think it would be possible to make the form editable vs. readonly?
Thanks,
Holly
Holly,
I’m working on a “Page Layout Form” component that’ll let one create a basic record form using a specified page layout. It’ll be separate from this component but theoretically could be combined into one. Stay tuned.
Hey Holly,
Check out the Page Layout Form component for a editable version: https://metillium.com/2018/09/page-layout-form-lightning-component-prototype/
Is it possible to get the pageLayout name assigned to the current user for the record dynamically instead of passing it? That would make the component even more effective?
I have tried this code but blank page is getting displayed.Could you please let me know the changes that i need to do in this code