8

Somewhat flummoxed with this lightning component.

The use case is simple: Intercept the save event on a record edit, grab the new field values and do 'stuff' before saving the record.

Example

  1. User edits an Account record and updates the Credit__c field
  2. User hits 'Save'
  3. Controller Handler intercepts Save, grabs new Credit__c value and does 'stuff'
  4. If stuff okay then go ahead with save

Using force:recordData I can intercept the save, iterate through the targetFields attribute, grab Credit__c, do stuff and then go ahead and save or not. BUT I cannot see a way to show the record using the page layout (we have many complex page layouts so coding fields manually is not an option)

Using lightning:recordForm I can show all the fields as per page layout and intercept the save but don't see a way to access the new field values before saving the record.

I imagine this is a fairly common scenario but I can't see a way through.

Code for OPTION 1 : Using force:recordData (you can access the changed data but do not have page layouts)

<!-- recordData.cmp -->

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

<force:recordData aura:id="recordHandler"
  recordId="{!v.recordId}"            
  targetFields="{!v.recordFields}"    
  targetError="{!v.recordError}"     
  recordUpdated="{!c.handleRecordUpdated}"
  layoutType="FULL"
  mode="EDIT"                      
/>

<!-- This component does not provide page layout  rendering  so you have to manually display editing fields  -->
<div class="Record Details">
    <lightning:card iconName="action:edit" title="{! 'Edit ' + v.recordFields.Name}">
      </div>
        <lightning:input label="Credit" value="{!v.recordFields.Credit__c }"/>
          <!-- show other editing fields here -->
        <lightning:button label="Save" variant="brand" onclick="{!c.handleSave}" />
      </div>
    </lightning:card>
</div>

// recordDataController.js

handleSave : function(component, event, helper) {
var recFields = component.get('v.recordFields');

// Iterate through new field value before saving and do stuff
Object.getOwnPropertyNames(recFields).forEach(
    function (val, idx, array) {
        if (recFields[val] != null){
            doStuff(val, recFields[val]))
        }
    });

  if (isStuffSuccess()) {
    helper.saveRecord(component);
  } else {
    //show error
  }
},

Code for OPTION 2 : Using lightning:recordData (you have page layouts but cannot access the changed data)

<!--recordForm.cmp -->


<aura:component implements="flexipage:availableForRecordHome,force:hasRecordId" access="global" >

  <!--Specify fields or use page layout fields -->
  <aura:attribute name="fields" type="List" default=""/>

  <lightning:recordForm 
     recordId = "{! v.recordId}"
     fields = "{!v.fields}"
     objectApiName="Account" 
     layoutType="Full" 
     columns = "2"
     mode = "Edit"
     onload = "{!c.handleLoad}"
     onsubmit = "{!c.handleSubmit}"
     onsuccess = "{!c.handleSuccess}" 
     onerror = "{!c.handleError}"               
  />
  <lightning:messages />

    <!-- This component automatically shows fields honouring page layout -->

</aura:component>

.

// recordFormController.js

    handleSubmit: function(component, event, helper) {
      console.log("> handleSubmit");   
      event.preventDefault();

      // How to access changed Account field values?
    }

p.s. could someone with more cred than me create a Lightning:recordForm tag so us stackexchange noobs can tag posts properly :)

4
  • 1
    mind sharing your code? it will be easier to assist
    – glls
    Commented Jun 9, 2018 at 23:54
  • I hope I have enough cred for you.
    – sfdcfox
    Commented Jun 10, 2018 at 6:39
  • 1
    haha, @sfdcfox if you could sell credits you'd be a millionaire :)
    – Etienne
    Commented Jun 11, 2018 at 9:55
  • We have similar requirements. I succeeded in preserving configured fields using recordData to get fields and a recordEditForm to display / manipulate them (prefill, post processing). What I did not succeed in is preserving the order of fields or columns of the layout. Commented Jun 11, 2018 at 10:48

1 Answer 1

5

Your option 2, using lightning:recordForm, is the solution. You just need to update your submit handler code.

In your cmp:

<lightning:recordForm aura:id="form" recordId = "{! v.recordId}" fields = "{!v.fields}" objectApiName="Account" layoutType="Full" columns = "2" mode = "Edit" onload = "{!c.handleLoad}" onsubmit = "{!c.handleSubmit}" onsuccess = "{!c.handleSuccess}" onerror = "{!c.handleError}"/>

And in your controller:

handleSubmit: function(component, event, helper) { event.preventDefault(); // stop the form from submitting var fields = event.getParam('fields'); fields.Name = '1 Market Street'; // passing whatever you want here component.find('form').submit(fields); }

3
  • Kevin, thank you, your solution works beautifully, exactly what I wanted.
    – Etienne
    Commented Jun 13, 2018 at 10:09
  • any way to do this dynamically? im looking to use a variable for the field i want to validate. like fields[var] or fields.get(var)
    – textual
    Commented Aug 7, 2018 at 1:35
  • Yes, it’s JavaScript so you can use any logic you like. Commented Sep 1, 2019 at 6:11

You must log in to answer this question.