Lightning Aura Components – Editing Fields Before Submitting in lightning:recordEditForm

I am trying to create a page so that I can create multiple sObject records in a single button click, with the help of lightning:recordEditForm component.

I checked the below link, and looks like this might work.
Multiple lightning:recordEditForm

The issue is that before submitting the form, I want to edit the values for each of the record. So

  1. Is there any way to access the field values, update it and then submit?
  2. OR is there any way to send this data to an Apex Controller where I can edit records before saving?

This is how my code looks:

<aura:iteration items="{!v.data}" var="prod">
    <lightning:recordEditForm aura:id="recordEditForm" objectApiName="OrderItem">
    <div class="slds-grid slds-wrap">

        <lightning:messages/>
        <lightning:inputField fieldName="Quantity"/>
        <lightning:inputField fieldName="PaymentTerms__c"/>
    </div>
    </lightning:recordEditForm>
</aura:iteration>

<lightning:button variant="brand" label="Next" onclick="{!c.handleSubmit}"/>

And this is the controller method:

handleSubmit: function (component, event, helper) {
    const editForms = component.find('recordEditForm');
    const forms = [].concat(editForms || []);
    forms.forEach((form)=>{
        // Retrieve the field values, update it
        // ...
        // ...
        form.submit();
    });
},

I checked this post below by Alba Rivas; she is manipulating the field values on submit controller method of lightning:recordEditForm. I just need this capability, but in my own defined controller method.
https://albasfdc.com/2018/03/19/creating-pre-populated-records-with-lightningrecordeditform/

Best Answer

  1. Is there any way to access the field values, update it and then submit?

Yes (not really a good approach IMO, but it works). The idea is to access the input fields directly, instead of trying to access the fields thru record edit form.

Introduce aura:id for all the input fields. For example, <lightning:inputField aura:id="qtyInputFld" fieldName="Quantity"/>.

The controller JS method should be as shown below. This snippet shows the field update for only one field and I've used forEach just to illustrate how the field can be accessed, In your case, you should write the code for all fields and if you need to update only specific records, you would need to use other JS methods like map. Note that the order in which the inputField component instances are retrieved by this code will same as the order in which they are displayed in the UI.

handleSubmit: function (component, event, helper) {
    // Retrieve the fields and update them
    component.find('qtyInputFld').forEach(field => {
        // field.get('v.value') will get you the current field value
        field.set('v.value', '<Replace the value here>');
    }); 
    
    // Field updates made in the above code will persist in the component.
    // Now, you can call submit method on each instance of recordEditForm
    const editForms = component.find('recordEditForm');
    const forms = [].concat(editForms || []);
    forms.forEach((form)=>{
        form.submit();
    });
}

If you prefer better control over the manipulating the fields, then you should consider either of these approaches:

  • Write custom JS method [to access the fields, construct an array (or objects) using the accessed fields, replicate the changes back into the component etc.] using the similar code as shown above.
  • Write an apex class to perform DML and get rid of the submit method (of recordEditForm) in the controller JS. Construct an array or object or string (using the field values) and pass it to the apex method.
  1. OR is there any way to send this data to an Apex Controller where I can edit records before saving?

If you want to pass the data to a custom apex class, then YES (as mentioned earlier). But if you want to use submit method of the recordEditForm, then the answer is NO. Because by using this method, you are delegating the task to lightning data service. I don't think Salesforce has provided any way to intercept this call.

Additional Info:

  • If you look into the details of the proxy object editForms in your current code and try to hack into it, you may find some other approach to access the field values. But, I feel that it will not be worth the time (for this given requirement). Besides, this proxy object is deeply nested and not sure if Salesforce updates in future would change the proxy object structure (in terms of both deprecating existing methods/ entries as well as introducing new ones).
  • You cannot use the onchange handler on the inputField because setting the values of the field using this handler works only during loading and before the user has entered any value into the field. After the user enters a value in the field, updating the field value doesn't work (but accessing the field value work). This info can be found here.
Related Topic