I'm trying to save custom object's records using lightning component , the form contain lookup fields ( multi select records ) , i have developed a LC to be able to select multi records on custom object's lookup field

Code :

<aura:component implements="flexipage:availableForRecordHome,force:hasRecordId" controller="SaveFormVisitReport" >
<aura:attribute name="recordId" type="String" />
<aura:attribute name="selectedLookUpRecords" type="Contact" default="[]"/>
<aura:attribute name="selectedLookUpRecords1" type="User" default="[]"/>
<aura:attribute name="newRecord" type="Visit_Report__c" default="{ 'sobjectType': 'Visit_Report__c',                                                                      'Visit_Type__c':'',                                                                        'Contact__c':'',                                                                        'User__c':'',                                                                       'Account__c':'',                                                                       'Comments__c':''}"/>
<lightning:recordEditForm objectApiName="Visit_Report__c">
<lightning:messages />
<lightning:inputField fieldName="Visit_Type__c" aura:id="type"/>   
<lightning:inputField fieldName="User__c" aura:id="user"/> 
<c:reUsableMultiSelectLookup objectAPIName="Contact"
                               label="Contact Name" aura:id="cont"/>
<c:reUsableMultiSelectLookup objectAPIName="User"
                               label="Assigned to" aura:id="user"/> 
<lightning:inputField fieldName="Account__c" aura:id="acc"/> 
<lightning:inputField fieldName="Comments__c" aura:id="comm"/>
                label="Create new">

> Form :

enter image description here


enter image description here

Any suggestion on how to solve this issue ? should i develop custom controller?

Thanks in advance,


As @sfdcfox has suggested, first you need to create a submit handler, so modify the lightning:recordEditForm element to include onsubmit like this:

<lightning:recordEditForm aura:id="myform" objectApiName="Visit_Report__c" onsubmit="{!c.handleSubmit}">

You then need to extract values from your selected Contacts and Users and assign these values to fields of your Visit_Report__c SObject, which you can do by making your handler function like this:

   handleSubmit: function (component, event) {

        const fields = event.getParam('fields');
        fields.Contact__c = component.get('v.selectedContacts')[0].Id;
        fields.User__c = component.get('v.selectedUsers')[0].Id;


Note, there is an important limitation to this solution: You can only assign a single value from your reUsableMultiSelectLookup components to the existing fields on the Visit_Report__c SObject.

Since you want a multiselect, you probably want/need somewhere to put the remaining values. One possibility would be to reverse the relationships such that the Contacts and Users are the parents instead of the children, but offhand I don't know whether you'd be able to update the parents using lightning:recordEditForm. Also, depending upon your use case, you might actually want/need some junction sobjects, and I'm pretty sure you would need to take a different approach to saving your data if you need to create a collection of junctions objects every time you save this form.

If your comment field is large enough (or you create another text field), you could squirrel all your Ids into the text field in some structured format and then use an Apex trigger on Visit_Report__c to create the appropriate relations on the server side, but at that point it would probably be better to use an Apex controller more specific to this form instead.


You need to handle the lightning:recordEditForm's onsubmit handler. You can set up any additional data you want to submit.

<lightning:recordEditForm objectApiName="Visit_Report__c" onsubmit="{!c.handleSubmit}">


handleSubmit: function(c, e, h) {
    var input1 = c.get("v.selectedLookUpRecords");
    var input2 = c.get("v.selectedLookUpRecords1");
  • it seems that it doesn't work .. CMP : <lightning:recordEditForm aura:id="myform" objectApiName="Visit_Report__c" onsubmit="{!c.handleSubmit}"> JS : handleSubmit: function(component, event, handler) { var input1 = component.get("v.selectedLookUpRecords"); var input2 = component.get("v.selectedLookUpRecords1"); var input3 = component.find("acc").get("v.value"); component.find('myform').submit(input1); component.find('myform').submit(input2); component.find('myform').submit(input3); – user81938 Apr 19 '20 at 17:55
  • @FirasTaamallah No, you need to set the field values you wish to save to the record, then call submit with no parameters. See the docs. – sfdcfox Apr 19 '20 at 18:50
  • can you please share an example , thanks – user81938 Apr 19 '20 at 20:43
  • 1
    We didn't. Your account is under a question ban automatically imposed by the system based on community and moderation response to your question history. Please review the linked article to understand the cause and available remedies. The moderators cannot lift a system-imposed question ban. – David Reed Jun 15 '20 at 14:36
  • 1
    The moderators do not have the power to impose or lift question or answer bans. The only similar action we can take is to suspend a user from the site, which we do very infrequently. You have not been suspended and would be clearly advised if that were the case. – David Reed Jun 15 '20 at 14:37

With regard to actually saving multiple records for both Contacts and Users, as discussed in my previous answer, you need somewhere to save them and a server-side controller.

By creating junction objects ("Visit_Report_Assignee__c" and "Visit_Report_Contact__c") I was able to make this work.

This is my complete client-side/Aura VisitReportFormController.js:

    handleSubmit: function (component, event) {

        const fields = event.getParam('fields');
        fields.Account__c = component.get('v.recordId');

        const action = component.get('c.saveVisitReport');
            visitReport: fields,
            contactList: component.get('v.selectedContacts'),
            userList: component.get('v.selectedUsers')
        action.setCallback(this, function (response) {
            let title = '';
            let type = '';
            let message = '';
            if ('SUCCESS' === response.getState()) {
                const value = response.getReturnValue();
                title = 'Success';
                type = 'success';
                message = `'${value.Subject__c}' is Created Successfully as record ${value.Id}`;
            } else {
                title = 'Error';
                type = 'error';

                const errors = response.getError();
                const error = errors[0];
                message = (error && error.message)
                    ? `Error message: ${error}`
                    : 'Unknown error';

            const toastEvent = $A.get("e.force:showToast");
                "title": title,
                "type": type,
                "message": message


It calls the saveVisitReport method on this server-side/Apex controller:

public inherited sharing class VisitReportFormAuraCtrl {
    private XAP_DAO_TRANS_MultiDmlOperationProcessor multiDmlOperationProcessor;

    private VisitReportFormAuraCtrl(XAP_DAO_TRANS_MultiDmlOperationProcessor multiDmlOperationProcessor) {
        this.multiDmlOperationProcessor = multiDmlOperationProcessor;

    private VisitReportFormAuraCtrl() {

    private static VisitReportFormAuraCtrl instance;
    public static VisitReportFormAuraCtrl getInstance() {
        if (instance == null) {
            instance = new VisitReportFormAuraCtrl();
        return instance;

    public static Visit_Report__c saveVisitReport(
            Visit_Report__c visitReport,
            List<Contact> contactList,
            List<User> userList
    ) {
        return VisitReportFormAuraCtrl.getInstance()
                .save(visitReport, contactList, userList);

    private Visit_Report__c save(Visit_Report__c visitReport, List<Contact> contactList, List<User> userList) {
        this.multiDmlOperationProcessor.process(new List<XAP_DAO_TRANS_DmlOperationIntf>{
                new VisitReportInserter(visitReport),
                new VisitReportRelationInserter(contactList, userList)
        return visitReport;

XAP_DAO_TRANS_MultiDmlOperationProcessor is from a library I previously developed. Applying the Command pattern, it enables the consumer to execute multiple database operations; after each DML operation, it checks whether operations succeed or fail and will handle the rollbacks if necessary (so you don't need to fill your code with these checks).

You can find the complete solution here: https://github.com/nilvon9wo/VisitReportFormLightningComponent

Your Answer

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