Editing a Record

The simplest way to create a form that enables you to edit a record is to use the lightning:recordForm component. If you want to customize the form layout or preload custom values, use lightning:recordEditForm. If you want to customize a form more than the form-based components allow, use force:recordData.

Edit a Record using lightning:recordForm

To edit a record using lightning:recordForm, provide the record ID and object API name. When you provide a record ID, view mode is the default mode of this component, which displays fields with edit icons. If you click an edit icon, all fields in the form become editable.

This example creates a form that lets users update fields on an account record when an edit icon is clicked. It displays the fields from the compact layout in two columns. Add this example component to an account record page. The component inherits the record ID via the force:hasRecordId interface.

1<aura:component implements="flexipage:availableForRecordHome, force:hasRecordId">
2    <lightning:recordForm 
3        recordId = "{!v.recordId}"
4        objectApiName="Account"
5        layoutType="Compact"
6        columns="2" />
7</aura:component>

When the record is saved successfully, all components that contain the updated field values are refreshed automatically.

Add mode="edit" to transform the form to one that displays input fields for editing. The form displays a Save button that updates the record, and a Cancel button that reverts changes.

1<aura:component implements="flexipage:availableForRecordHome, force:hasRecordId">
2    <lightning:recordForm
3        recordId = "{!v.recordId}"
4        objectApiName="Account"
5        layoutType="Compact"
6        mode="edit" />
7</aura:component>

Customize Error Handling in lightning:recordForm

To customize the behavior when a record is saved successfully, use the onsuccess event handler. Errors are automatically handled and displayed. To customize them, use the onerror event handler.

1<aura:component implements="flexipage:availableForRecordHome, force:hasRecordId">
2
3    <!-- Displays a toast notification -->
4    <lightning:notificationsLibrary aura:id="notifLib" />
5    <lightning:recordForm
6        recordId = "{!v.recordId}"
7        objectApiName="Account"
8        layoutType="Compact"
9        mode="edit" 
10        onsuccess="{!c.handleSuccess}"
11        onerror="{!c.handleError}"/>
12</aura:component>

A toast notification is displayed when a record is saved successfully or when an error is encountered during save.

1({
2    handleSuccess: function (cmp, event, helper) {
3        cmp.find('notifLib').showToast({
4            "title": "Record updated!",
5            "message": "The record "+ event.getParam("id") + " has been updated successfully.",
6            "variant": "success"
7        });
8    },
9
10    handleError: function (cmp, event, helper) {
11        cmp.find('notifLib').showToast({
12            "title": "Something has gone wrong!",
13            "message": event.getParam("message"),
14            "variant": "error"
15        });
16    }
17})

For more information, see lightning:recordForm.

Note

Edit a Record with a Custom Layout Using lightning:recordEditForm

To provide a custom layout for your form fields, use the lightning:recordEditForm component.

Pass in the fields to lightning:inputField, which displays an input control based on the record field type.

This example displays a form with two fields using a custom layout. Add this example component to an account record page.

1<aura:component implements="flexipage:availableForRecordHome, force:hasRecordId">
2    <lightning:recordEditForm 
3        recordId="{!v.recordId}"
4        objectApiName="Account">
5        <lightning:messages />
6            <div class="slds-grid">
7                <div class="slds-col slds-size_1-of-2">
8                    <lightning:inputField fieldName="Name"/>
9                </div>
10                <div class="slds-col slds-size_1-of-2">
11                    <lightning:inputField fieldName="Industry"/>
12                </div>
13            </div>
14        <lightning:button class="slds-m-top_small" type="submit" label="Create new" />
15    </lightning:recordEditForm>
16</aura:component>

When a server error is encountered, lightning:recordEditForm displays an error message above the form fields using the lightning:messages component. Alternatively, provide your own error handling using the onerror event handler.

Another feature that lightning:recordEditForm provides that’s not available with lightning:recordForm is displaying the form with custom field values, as shown in the next section.

Prepopulate Field Values

To provide a custom field value when the form displays, use the value attribute on lightning:inputField. If you're providing a record ID, the value returned by the record on load does not override this custom value.

Alternatively, set the field value using this syntax.

1cmp.find("nameField").set("v.value", "My New Account Name");

For more information, see lightning:recordEditForm.

Note

If you require more customization when creating a record than what lightning:recordForm and lightning:recordEditForm allow, consider using force:recordData.

Edit a Record via a Custom User Interface Using force:recordData

To edit and save a record using force:recordData, call saveRecord and pass in a callback function to be invoked after the save operation completes. The save operation is used in two cases.
  • To save changes to an existing record
  • To create and save a new record

To save changes to an existing record, load the record in EDIT mode and call saveRecord on the force:recordData component.

To save a new record, and thus create it, create the record from a record template, as described in Creating a Record. Then call saveRecord on the force:recordData component.

Load a Record in EDIT Mode

To load a record that might be updated, set the force:recordData tag’s mode attribute to “EDIT”. Other than explicitly setting the mode, loading a record for editing is the same as loading it for any other purpose.

Since Lightning Data Service records are shared across multiple components, loading records provides the component with a copy of the record instead of a direct reference. If a component loads a record in VIEW mode, Lightning Data Service automatically overwrites that copy with a newer copy of the record when the record is changed. If a record is loaded in EDIT mode, the record is not updated when the record is changed. This prevents unsaved changes from appearing in components that reference the record while the record is being edited, and prevents any edits in progress from being overwritten. Notifications are still sent in both modes.

Note

Call saveRecord to Save Record Changes

To perform the save operation, call saveRecord on the force:recordData component from the appropriate controller action handler. The saveRecord method takes one argument—a callback function to be invoked when the operation completes. This callback function receives a SaveRecordResult as its only parameter. SaveRecordResult includes a state attribute that indicates success or error, and other details you can use to handle the result of the operation.

Saving a Record

The following example illustrates the essentials of saving a record using Lightning Data Service. It’s intended for use on a record page. The record ID is supplied by the implicit recordId attribute added by the force:hasRecordId interface.

ldsSave.cmp
1<aura:component implements="flexipage:availableForRecordHome,force:hasRecordId">
2
3    <aura:attribute name="record" type="Object"/>
4    <aura:attribute name="simpleRecord" type="Object"/>
5    <aura:attribute name="recordError" type="String"/>
6
7    <force:recordData aura:id="recordHandler"
8      recordId="{!v.recordId}"
9      fields="Name,BillingState,BillingCity"
10      targetRecord="{!v.record}"
11      targetFields="{!v.simpleRecord}"
12      targetError="{!v.recordError}"
13      mode="EDIT"
14      recordUpdated="{!c.handleRecordUpdated}"
15      />
16
17    <!-- Display a lightning card with details about the record -->
18    <div class="Record Details"> 
19        <lightning:card iconName="standard:account" title="{!v.simpleRecord.Name}" >
20            <div class="slds-p-horizontal--small">
21                <p class="slds-text-heading--small">
22                    <lightning:formattedText title="Billing State" value="{!v.simpleRecord.BillingState}" /></p>
23                <p class="slds-text-heading--small">
24                    <lightning:formattedText title="Billing City" value="{!v.simpleRecord.BillingCity}" /></p>
25            </div>
26        </lightning:card>
27    </div>
28
29    <!-- Display an editing form -->
30    <div class="Record Details">
31        <lightning:card iconName="action:edit" title="Edit Account">
32            <div class="slds-p-horizontal--small">
33               <lightning:input label="Account Name" value="{!v.simpleRecord.Name}"/>
34               <br/>
35               <lightning:button label="Save Account" variant="brand" onclick="{!c.handleSaveRecord}" />
36            </div>
37        </lightning:card>
38    </div>
39    
40    <!-- Display Lightning Data Service errors, if any -->
41    <aura:if isTrue="{!not(empty(v.recordError))}">
42        <div class="recordError">
43            {!v.recordError}</div>
44    </aura:if>
45</aura:component>
To improve performance, we recommend using the fields attribute to query only the fields you need. Use layoutType only if you expect to display or edit a large number of fields on the compact or full layout.

To edit the constituent fields on compound fields, such as the FirstName and LastName fields in the Name compound field, create a separate lightning:input component for {!v.simpleRecord.FirstName} and {!v.simpleRecord.LastName}.

Note

This component loads a record using force:recordData set to EDIT mode, and provides a form for editing record values. (In this simple example, just the record name field.)
ldsSaveController.js
1({
2    handleSaveRecord: function(component, event, helper) {
3        component.find("recordHandler").saveRecord($A.getCallback(function(saveResult) {
4            // use the recordUpdated event handler to handle generic logic when record is changed
5            if (saveResult.state === "SUCCESS" || saveResult.state === "DRAFT") {
6                // handle component related logic in event handler
7            } else if (saveResult.state === "INCOMPLETE") {
8                console.log("User is offline, device doesn't support drafts.");
9            } else if (saveResult.state === "ERROR") {
10                console.log('Problem saving record, error: ' + JSON.stringify(saveResult.error));
11            } else {
12                console.log('Unknown problem, state: ' + saveResult.state + ', error: ' + JSON.stringify(saveResult.error));
13            }
14        }));
15    },
16
17    /**
18     * Control the component behavior here when record is changed (via any component)
19     */
20    handleRecordUpdated: function(component, event, helper) {
21        var eventParams = event.getParams();
22        if(eventParams.changeType === "CHANGED") {
23            // get the fields that changed for this record
24            var changedFields = eventParams.changedFields;
25            console.log('Fields that are changed: ' + JSON.stringify(changedFields));
26            // record is changed, so refresh the component (or other component logic)
27            var resultsToast = $A.get("e.force:showToast");
28            resultsToast.setParams({
29                "title": "Saved",
30                "message": "The record was updated."
31            });
32            resultsToast.fire();
33
34        } else if(eventParams.changeType === "LOADED") {
35            // record is loaded in the cache
36        } else if(eventParams.changeType === "REMOVED") {
37            // record is deleted and removed from the cache
38        } else if(eventParams.changeType === "ERROR") {
39            // there’s an error while loading, saving or deleting the record
40        }
41    }
42})
The handleSaveRecord action here is a minimal version. There’s no form validation or real error handling. Whatever is entered in the form is attempted to be saved to the record.

If you are creating multiple instances of force:recordData on a page, provide your saveRecord and recordUpdated handlers accordingly. For example, if you have two instances of force:recordData that updates the same record, assign a different aura:id to each instance, such that saveRecord is called uniquely, and subsequently the recordUpdated handler.