I was recently working on creating a utility LWC component for displaying Salesforce record data. This component is unique in that it can be used with both standard and custom objects, and t here is no need to create a record form for each object; simply drag and drop this component on any record form page in Lightning App Builder, provide the API name of the object, and supply a few more parameters, and voila! The record form will be generated based on the page layout. By overriding the new and edit buttons, this component may be used to create or change a record.
This component relies on the fact that every record is associated with a page layout, and it requires this information when it is instantiated. If an object has record types, a mapping must be supplied. This component does not currently accept compound fields, but as far as I can tell, it is possible.
I learnt a lot while working on this component, which I'd like to share in this blog.
lightning-record-edit-form
can be used for both creating and editing a record. To customize the behaviour of your form when it loads, use theonload
attribute to specify event handlers. This is how you gain access to the recordasync handleRecordEditFormLoad(event) { const record = this.recordId ? event.detail.records[this.recordId] : event.detail.record; ... ... }
You can use the below piece of code to display the form once you've retrieved the page layout data (see below).
get sections() { return this.layoutSections?.map((layoutSec) => { const layoutSection = { ...layoutSec }; const { layoutColumns } = layoutSection; layoutSection.layoutColumns = layoutColumns?.map((layoutColumn, id) => { const { layoutItems } = layoutColumn; layoutColumn = { ...layoutColumn, id }; layoutColumn.layoutItems = layoutItems ?.map((layoutItem, id) => { layoutItem = { ...layoutItem, id }; return layoutItem; }); return layoutColumn; }); return layoutSection; }); }
Use
getRecord
wire adapter to get record’s data.@wire(getRecord, { recordId: '$recordId', layoutTypes: ['Full'], modes: ['View'] }) wiredRecord({ error, data }) { if (data) { this.recordData = data; ... ... } }
During record creation, this wire adapter won't fetch
recordData
for us. As a result, use theonload
attribute oflightning-record-edit-form
(see above). TherecordData
will be auto-populated with default values, like OwnerId, so you won’t have to populate it yourself.
When the user is filling up information, use
onchange
event handler oflightning-input-field
to update the record data in memory.handleInputChange(event) { event.preventDefault(); this.recordData.fields[event.target.dataset.api].value = event.detail.value; }
If you don't include a
lightning-button
with type="submit" insidelightning-record-edit-form
, this is how you can save the recordhandleModalSave() { const data = this.recordData; this.template.querySelector('lightning-record-edit-form').submit(data); }
There is a wire adapter
getRecordUi
that gets layout information, metadata, and data to build UI for one or more records. However, for unknown reasons at this time, it is marked as deprecated. As a result, I had to use metadata API to read the page layout information before the form could be loaded.
Make sure that you check out the UI API Playground provided by Philippe Ozil to study UI APIs and comprehend the type of data JSON gives. Or else use Chrome debugger tools.
Refer SLDS library as much as possible to maintain the aesthetics of Salesforce platform so that you can serve majority of the use cases.