5

I'm trying to disable some surrounding components based on the mode attribute within lightning:recordForm (i.e. anytime I'm in edit mode, I'd like to disable a lightning:buttonMenu that sits just outside the lightning:recordForm).

I'm using an aura attribute v.formMode to store the default mode "view", but it doesn't seem to update itself when I double click in the UI to make inline edits.

I looked through both lightning:recordForm and lightning:recordEditForm documentation, but there's no special event to catch when the mode is changing, and it doesn't seem to auto-update the binded aura variable.

<lightning:recordForm 
    aura:id="recordForm"
    recordId="{!v.recordId}"
    objectApiName="Case"
    fields="{!v.fields}"
    columns="2"
    mode="{! v.formMode }" />

Any ideas?

2 Answers 2

1

Mode initialization works only once. After you manually change mode in lightning:recordForm, it doesn't fire neither component, nor application change event(tested in Salesforce Lightning Inspector).

You can handle changes of mode via onload handler. But keep in mind, when component is rendering, it fires onload twice. That's why you need to skip first time onload.

Also, when you've successfully saved changes, it is additionally fires onload. So, onsuccess should set formMode to 'view'.

Component

<aura:component implements="flexipage:availableForRecordHome,force:hasRecordId">
    <aura:attribute name="skipFirstLoad" type="Boolean" default="true"/>
    <aura:attribute name="formMode" type="String" default="view" access="private"/>

    <lightning:recordForm
            aura:id="recordForm"
            recordId="{!v.recordId}"
            objectApiName="Case"
            fields="{!v.fields}"
            columns="2"
            mode="{#v.formMode}"
            onload="{!c.loadHandler}"
            onsuccess="{!c.successHandler}"
    />
</aura:component>

JS Controller

({
    loadHandler : function(component, event, helper) {
        if(component.get('v.skipFirstLoad')) {
            component.set('v.skipFirstLoad', false);
            return;
        }
        component.set('v.formMode', component.get('v.formMode') === 'view' ? 'edit' : 'view');
    },

    successHandler : function(component, event, helper) {
        component.set('v.formMode', 'view');
    }
});
1
  • 1
    Thanks, didn't know about the onload behavior and you confirmed my suspicions about mode Aug 5, 2019 at 9:53
1

mode on recordForm is 1-way binding. When the mode of recordForm changes, it does not automatically reflect in the parent component attribute binding. So we need to implement some logic to come around that limitation which is implemented in example below:

cmp:

<aura:component implements="lightning:isUrlAddressable" access = "GLOBAL">

    <aura:attribute name="mode" type="String" default="view" />
    <aura:attribute name="showEditBtn" type="Boolean" default="true" />
    <aura:attribute name="initDone" type="Boolean" default="false" />

    <div class="slds-theme_default">
        <lightning:recordForm recordId="00128000009j45sAAA"
                              objectApiName="Account"
                              layoutType="Full"
                              onload="{!c.handleLoad}"
                              onsuccess="{!c.handleSuccess}"
                              columns="2"
                              mode="{#v.mode}"/>
        mode - {!v.mode}
    </div>

</aura:component>
  1. Notice the 1-time binding # for mode. This is needed so that form does not go into infinite loop of edit and view when setting the mode in onload.

  2. When recordForm is initialised, onload is triggered 2 times (before and after loading form), and so mode turns from view to edit and again back to view, so handler for this is not much required (only not to make it more complex).

  3. Also on onsuccess, first onload fires which makes mode as edit, so we have to set it back to view on handleSuccess method.

  4. After saving, if an error occurs because of validation rules, even then onload fires 2 times (Once immediately onsubmit when Save is clicked and 2nd time when it shows error - onerror). So again, mode will be changed back to edit mode, and hence no handler is required even in this case.

and its JS:

({
    handleLoad : function(component, event, helper) {
        console.log("loaded record form");
        let mode = (component.get("v.mode")==='view') ? 'edit' : 'view';
        component.set("v.mode",mode);
    },
    handleSuccess : function(component, event, helper) {
        component.set('v.mode', 'view');
    }
})

Note: I already pointed this behaviour of mode of recordForm in this answer. But I think nobody noticed.

3
  • Thank you for the thorough explanation here - I learned a lot. I think I'll have to revisit the original requirements as mode is not auto-updating itself Aug 5, 2019 at 9:52
  • @BrianMiller. WC ). Pls mark as solved if solved Aug 5, 2019 at 11:08
  • Keeping it open (i.e. not solved) just in case someone else has a better idea on how to achieve my original question - to disable surrounding components based on the UI change from view to edit mode Aug 5, 2019 at 12:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.