> For the complete documentation index, see [llms.txt](https://docs.gridmate.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.gridmate.io/package-reference/components-library/gm-enhanced-record-layout.md).

# GM - Enhanced Record Layout

(gmpkg/recordLayoutLWC)

## **Documentation**

**GM - Enhanced Record Layout** component displays and edits a record using a JSON layout configuration, the same one used by [GM - Record Layout](/package-reference/components-library/gm-record-layout.md) and [GM - Record Layout (LWC)](/package-reference/components-library/gm-record-layout-lwc.md). It is a native Lightning Web Component: it can be placed on record, app, home and Experience Cloud pages, on desktop and on phone, without an Aura wrapper.

On top of the layout JSON, it supports layout actions, validation rules, an Apex validation action and a custom metadata configuration. See [Enhanced Record Layout](/advanced-guides/enhanced-record-layout.md) for the walkthrough.

## **Specification**

<table><thead><tr><th width="243.388916015625">Property</th><th>Description</th></tr></thead><tbody><tr><td><strong>Record Id</strong></td><td>Id of the record to display. Leave empty on a record page.</td></tr><tr><td><strong>Layout Config</strong></td><td>Developer Name of a <strong>Record Layout</strong> custom metadata record. When set, the values of the record replace the properties below, including the empty ones.</td></tr><tr><td><strong>Object Name</strong></td><td>API name of the object to display.</td></tr><tr><td><strong>Record Id Field</strong></td><td>Field of the page record holding the Id of the record to display. <code>Id</code> when the component is placed on the record itself.</td></tr><tr><td><strong>Record Layout</strong></td><td>JSON layout: sections, rows, visibility, read-only and coloring rules, <code>validate</code> rules and <code>rulesMode</code>.</td></tr><tr><td><strong>Layout Actions</strong></td><td>JSON array of layout actions displayed in the header.</td></tr><tr><td><strong>Record Actions</strong></td><td>JSON array of record actions displayed in the record toolbar.</td></tr><tr><td><strong>Show Actions as Buttons</strong></td><td>Display the record actions as buttons instead of icons.</td></tr><tr><td><strong>Custom Visible Actions</strong></td><td>Number of record actions displayed before the overflow menu.</td></tr><tr><td><strong>Show Border</strong></td><td>Display the card border.</td></tr></tbody></table>

### Layout Actions

<table><thead><tr><th width="249.7822265625">Key</th><th>Description</th></tr></thead><tbody><tr><td><code>name</code></td><td>Unique name of the action.</td></tr><tr><td><code>label</code></td><td>Button label.</td></tr><tr><td><code>icon</code></td><td>Button icon, e.g. <code>utility:check</code>.</td></tr><tr><td><code>mode</code></td><td><code>view</code> or <code>edit</code>. Omit to display the action in both modes.</td></tr><tr><td><code>type</code></td><td><code>layout</code> (default) applies the <code>command</code> to the layout. <code>apex</code> runs the Apex validator.</td></tr><tr><td><code>stateful</code></td><td><code>layout</code> actions are toggles by default. Set to <code>false</code> for a one-shot action.</td></tr><tr><td><code>command</code></td><td><code>layout</code> actions only. <code>{ "id", "target": { "fields" | "sections" | "formula" }, "changes": { "hidden", "readOnly", "highlighted", "backgroundColor", "style" } }</code></td></tr><tr><td><code>apexClass</code></td><td><code>apex</code> actions only. Name of the <code>Callable</code> class.</td></tr><tr><td><code>params</code></td><td><code>apex</code> actions only. JSON object passed to the class.</td></tr><tr><td><code>successMessage</code></td><td><code>apex</code> actions only. Toast displayed when the class returns no error.</td></tr></tbody></table>

```json
{
    "name": "validateAccount",
    "label": "Validate",
    "icon": "utility:check",
    "type": "apex",
    "mode": "edit",
    "apexClass": "AccountLayoutValidator",
    "params": { "strict": true },
    "successMessage": "Account looks good"
}
```

### Apex Validator

The class referenced by `apexClass` implements `Callable`. It is invoked with the action `validate` and the following arguments:

| Argument     | Type                  | Description                                                   |
| ------------ | --------------------- | ------------------------------------------------------------- |
| `record`     | `SObject`             | The record with the values currently displayed, saved or not. |
| `objectName` | `String`              | API name of the object.                                       |
| `params`     | `Map<String, Object>` | The `params` of the layout action.                            |

It returns a `List<gmpkg.SaveHookManager.SaveHookResult>`. A result with `fields` is displayed under each field, a result without `fields` is displayed as a record-level error, an empty list displays the `successMessage`.

```java
global with sharing class AccountLayoutValidator implements Callable {
    global Object call(String action, Map<String, Object> args) {
        Account acc = (Account) args.get('record');
        List<gmpkg.SaveHookManager.SaveHookResult> results = new List<gmpkg.SaveHookManager.SaveHookResult>();

        if (acc.AccountSource == 'Web' && String.isBlank(acc.Phone)) {
            // Field-level: statusCode, message, fields
            results.add(
                new gmpkg.SaveHookManager.SaveHookResult(
                    'FIELD_CUSTOM_VALIDATION_EXCEPTION',
                    'Web accounts must have a phone number.',
                    new List<String>{ 'Phone' }
                )
            );
        }

        if (acc.Industry == 'Banking' && String.isBlank(acc.Description)) {
            // Record-level: statusCode, message
            results.add(
                new gmpkg.SaveHookManager.SaveHookResult(
                    'CUSTOM_VALIDATION_EXCEPTION',
                    'Banking accounts require a description.'
                )
            );
        }

        return results;
    }
}
```

### Record Layout Metadata

Custom metadata type **Record Layout** (`gmpkg__Record_Layout__mdt`). Set **Layout Config** to the **Record Layout Name** of a record to load the configuration from it.

<table><thead><tr><th width="257.4383544921875">Field</th><th>Component Property</th></tr></thead><tbody><tr><td><strong>Sobject</strong></td><td><strong>Object Name</strong></td></tr><tr><td><strong>Record Id Field</strong></td><td><strong>Record Id Field</strong></td></tr><tr><td><strong>Record Layout</strong></td><td><strong>Record Layout</strong></td></tr><tr><td><strong>Layout Actions</strong></td><td><strong>Layout Actions</strong></td></tr><tr><td><strong>Record Actions</strong></td><td><strong>Record Actions</strong></td></tr><tr><td><strong>Button Actions</strong></td><td><strong>Show Actions as Buttons</strong></td></tr><tr><td><strong>Visible Actions</strong></td><td><strong>Custom Visible Actions</strong></td></tr><tr><td><strong>Show Border</strong></td><td><strong>Show Border</strong></td></tr></tbody></table>

When **Layout Config** is set, every field of the metadata record replaces its property, including the empty ones.

## **API Reference**

{% tabs fullWidth="true" %}
{% tab title="recordLayoutLWC.js-meta.xml" %}

```xml
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>65.0</apiVersion>
    <masterLabel>GM - Enhanced Record Layout</masterLabel>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__RecordPage</target>
        <target>lightning__AppPage</target>
        <target>lightning__HomePage</target>
        <target>lightningCommunity__Page</target>
        <target>lightningCommunity__Default</target>
    </targets>
    <targetConfigs>
        <targetConfig targets="lightning__RecordPage,lightning__AppPage,lightning__HomePage">
            <property name="recordId" type="String" label="Record Id" />
            <property name="configName" type="String" label="Layout Config"
                      description="Developer Name of a Record Layout custom metadata record." />
            <property name="targetObjName" type="String" label="Object Name" />
            <property name="recordIdField" type="String" label="Record Id Field" />
            <property name="recordLayout" type="String" label="Record Layout"
                      description="JSON Record Layout, including required, validate, and rulesMode rules" />
            <property name="layoutActions" type="String" label="Layout Actions"
                      description="Optional JSON layout actions" />
            <property name="recordActions" type="String" label="Record Actions"
                      description="Optional JSON record actions shown in the record toolbar" />
            <property name="buttonActions" type="Boolean" label="Show Actions as Buttons"
                      description="Use buttons for actions instead of icons" />
            <property name="visibleActions" type="Integer" label="Custom Visible Actions"
                      description="# of visible custom actions" />
            <property name="showBorder" type="Boolean" label="Show Border" />
            <supportedFormFactors>
                <supportedFormFactor type="Large" />
                <supportedFormFactor type="Small" />
            </supportedFormFactors>
        </targetConfig>
    </targetConfigs>
</LightningComponentBundle>
```

{% endtab %}
{% endtabs %}
