# 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.

```xml
<aura:component implements="flexipage:availableForRecordHome, force:hasRecordId">
    <lightning:recordForm 
        recordId = "{!v.recordId}"
        objectApiName="Account"
        layoutType="Compact"
        columns="2" />
</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.

```xml
<aura:component implements="flexipage:availableForRecordHome, force:hasRecordId">
    <lightning:recordForm
        recordId = "{!v.recordId}"
        objectApiName="Account"
        layoutType="Compact"
        mode="edit" />
</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.

```xml
<aura:component implements="flexipage:availableForRecordHome, force:hasRecordId">

    <!-- Displays a toast notification -->
    <lightning:notificationsLibrary aura:id="notifLib" />
    <lightning:recordForm
        recordId = "{!v.recordId}"
        objectApiName="Account"
        layoutType="Compact"
        mode="edit" 
        onsuccess="{!c.handleSuccess}"
        onerror="{!c.handleError}"/>
</aura:component>
```

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

```javascript
({
    handleSuccess: function (cmp, event, helper) {
        cmp.find('notifLib').showToast({
            "title": "Record updated!",
            "message": "The record "+ event.getParam("id") + " has been updated successfully.",
            "variant": "success"
        });
    },

    handleError: function (cmp, event, helper) {
        cmp.find('notifLib').showToast({
            "title": "Something has gone wrong!",
            "message": event.getParam("message"),
            "variant": "error"
        });
    }
})
```

:::note
For more information, see [lightning:recordForm](https://developer.salesforce.com/docs/component-library/bundle/lightning\:recordForm/documentation).
:::

## 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.

```xml
<aura:component implements="flexipage:availableForRecordHome, force:hasRecordId">
    <lightning:recordEditForm 
        recordId="{!v.recordId}"
        objectApiName="Account">
        <lightning:messages />
            <div class="slds-grid">
                <div class="slds-col slds-size_1-of-2">
                    <lightning:inputField fieldName="Name"/>
                </div>
                <div class="slds-col slds-size_1-of-2">
                    <lightning:inputField fieldName="Industry"/>
                </div>
            </div>
        <lightning:button class="slds-m-top_small" type="submit" label="Create new" />
    </lightning:recordEditForm>
</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.

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

:::note
For more information, see [lightning:recordEditForm](https://developer.salesforce.com/docs/component-library/bundle/lightning\:recordEditForm/documentation).
:::

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](/docs/platform/aura-platform/guide/data-service-create-record.md#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.

:::note
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.
:::

## 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`

```xml
<aura:component implements="flexipage:availableForRecordHome,force:hasRecordId">

    <aura:attribute name="record" type="Object"/>
    <aura:attribute name="simpleRecord" type="Object"/>
    <aura:attribute name="recordError" type="String"/>

    <force:recordData aura:id="recordHandler"
      recordId="{!v.recordId}"
      fields="Name,BillingState,BillingCity"
      targetRecord="{!v.record}"
      targetFields="{!v.simpleRecord}"
      targetError="{!v.recordError}"
      mode="EDIT"
      recordUpdated="{!c.handleRecordUpdated}"
      />

    <!-- Display a lightning card with details about the record -->
    <div class="Record Details"> 
        <lightning:card iconName="standard:account" title="{!v.simpleRecord.Name}" >
            <div class="slds-p-horizontal--small">
                <p class="slds-text-heading--small">
                    <lightning:formattedText title="Billing State" value="{!v.simpleRecord.BillingState}" /></p>
                <p class="slds-text-heading--small">
                    <lightning:formattedText title="Billing City" value="{!v.simpleRecord.BillingCity}" /></p>
            </div>
        </lightning:card>
    </div>

    <!-- Display an editing form -->
    <div class="Record Details">
        <lightning:card iconName="action:edit" title="Edit Account">
            <div class="slds-p-horizontal--small">
               <lightning:input label="Account Name" value="{!v.simpleRecord.Name}"/>
               <br/>
               <lightning:button label="Save Account" variant="brand" onclick="{!c.handleSaveRecord}" />
            </div>
        </lightning:card>
    </div>
    
    <!-- Display Lightning Data Service errors, if any -->
    <aura:if isTrue="{!not(empty(v.recordError))}">
        <div class="recordError">
            {!v.recordError}</div>
    </aura:if>
</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.

:::note
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}`.
:::

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`

```javascript
({
    handleSaveRecord: function(component, event, helper) {
        component.find("recordHandler").saveRecord($A.getCallback(function(saveResult) {
            // use the recordUpdated event handler to handle generic logic when record is changed
            if (saveResult.state === "SUCCESS" || saveResult.state === "DRAFT") {
                // handle component related logic in event handler
            } else if (saveResult.state === "INCOMPLETE") {
                console.log("User is offline, device doesn't support drafts.");
            } else if (saveResult.state === "ERROR") {
                console.log('Problem saving record, error: ' + JSON.stringify(saveResult.error));
            } else {
                console.log('Unknown problem, state: ' + saveResult.state + ', error: ' + JSON.stringify(saveResult.error));
            }
        }));
    },

    /**
     * Control the component behavior here when record is changed (via any component)
     */
    handleRecordUpdated: function(component, event, helper) {
        var eventParams = event.getParams();
        if(eventParams.changeType === "CHANGED") {
            // get the fields that changed for this record
            var changedFields = eventParams.changedFields;
            console.log('Fields that are changed: ' + JSON.stringify(changedFields));
            // record is changed, so refresh the component (or other component logic)
            var resultsToast = $A.get("e.force:showToast");
            resultsToast.setParams({
                "title": "Saved",
                "message": "The record was updated."
            });
            resultsToast.fire();

        } else if(eventParams.changeType === "LOADED") {
            // record is loaded in the cache
        } else if(eventParams.changeType === "REMOVED") {
            // record is deleted and removed from the cache
        } else if(eventParams.changeType === "ERROR") {
            // there’s an error while loading, saving or deleting the record
        }
    }
})
```

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.

**See Also**

- [*Component Library*: `lightning:recordForm`](https://developer.salesforce.com/docs/component-library/bundle/lightning\:recordForm/documentation)
- [*Component Library*: `lightning:recordEditForm`](https://developer.salesforce.com/docs/component-library/bundle/lightning\:recordEditForm/documentation)
- [SaveRecordResult](/docs/platform/aura-platform/guide/data-service-saverecordresult.md)
- [Configure Components for Lightning Experience Record Pages](/docs/platform/aura-platform/guide/components-config-for-app-builder-record-home.md)
- [Configure Components for Record-Specific Actions](/docs/platform/aura-platform/guide/components-using-lex-s1-config-action-recordid.md)
