Sunday, August 11, 2019

Custom related list Lightning Components for adding contact

In this article i am going to explain how we can create a custom related list component for specific related list. I am going to create a custom contact related list component to add contact which will be exactly similar to standard related component.


Concept's tested:

1) lightning:card
2) force:recordData
3) lightning:overlayLibrary (To create modal box)
4) Dynamically creating component using $A.createComponent
5) force:navigateToRelatedList

customContact.cmp

<aura:component controller="customContactApex" implements="flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId" access="global" >
    <aura:handler name="init" value="{!this}" action="{!c.doInitialization}"/>
    <aura:attribute name="existingContactList" type="contact[]"/>
    <lightning:overlayLibrary aura:id="overlayLib"/>
    <aura:attribute name="contactNumber" type="string"/>
    <lightning:card title="{!v.contactNumber}" iconName="standard:contact">
        <aura:set attribute="actions">
            <lightning:button label="New" onclick="{!c.addContact}"/>
        </aura:set>
        <p class="slds-p-horizontal_small">
            <aura:iteration items="{!v.existingContactList}" var="con">
                <a href="{!'https://myknowndomain-dev-ed.lightning.force.com/'+con.Id}" >
                {!con.Name}
                 </a> 
                <p>Title:{!con.Title}</p>
                <p>Email:{!con.Email}</p>
                <p>Phone:{!con.Phone}</p> 
              <br></br>
            </aura:iteration>
        </p>
       <aura:set attribute="footer">
        <a href="javascript:void(0)" onclick="{!c.navigateToRelatedList}">
            View All
        </a>
        </aura:set>
    </lightning:card>
</aura:component>

customContactController.js

({
    doInitialization : function (component, event, helper) {
        var parentId=component.get("v.recordId");
        var action=component.get('c.getAllContact');
        var existingContactArray=[];
        var title="Contacts";
        action.setParams({
            accId : parentId
        });
       action.setCallback(this,function(response){     
            var state=response.getState();
            var responseLength=response.getReturnValue().length;
            if(state==="SUCCESS")
            {
             
                if(responseLength <= 3)
                {
                    component.set("v.contactNumber",title + ' ' + '(' + response.getReturnValue().length + ')');
                    component.set("v.existingContactList",response.getReturnValue());
                }
                else
                {
                    component.set("v.contactNumber",title + ' ' + '(' + '3+' + ')');
                 
                    for(var i=0; i<3;i++)
                        {
                            existingContactArray.push(response.getReturnValue()[i]);
                            //alert('response.getReturnValue(i)'+response.getReturnValue()[i]);
                        }
                    component.set("v.existingContactList",existingContactArray);
                }
             
            }
       
        });
        $A.enqueueAction(action);
    },
addContact: function(component, evt, helper) {
        //alert("Before creating Modal");
        var modalBody;

        $A.createComponent("c:contactForm", {accountId:component.get("v.recordId")},
           function(instanceOfContactForm, status) {
               if (status === "SUCCESS") {
                   modalBody = instanceOfContactForm;
                   component.find('overlayLib').showCustomModal({
                       header: "Create Contact",
                       body: modalBody,
                       showCloseButton: true,
                     
                       closeCallback: function() {
                         
                       }
                   })
               }                             
           });
    },
    navigateToRelatedList: function(component,event,helper){
   var rlEvent = $A.get("e.force:navigateToRelatedList");
   rlEvent.setParams({
      "relatedListId": "Contacts",
      "parentRecordId": component.get("v.recordId")
   });
   rlEvent.fire();
    }
 
 

})


contactForm.cmp

<aura:component implements="flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId" access="global" >
    <aura:attribute name="conFirstName" type="string" />
    <aura:attribute name="conLastName" type="string" />
    <aura:attribute name="conTitle" type="string" />
    <aura:attribute name="conDepartment" type="string" />
    <aura:attribute name="newContactRecord" type="Object"/>
    <aura:attribute name="contactFieldsToQuery" type="Object"/>
    <aura:attribute name="recordError" type="String"/>
    <aura:attribute name="accountId" type="string"/>
    <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
    <force:recordData aura:id="creatingContactRecordOnAccount"
                   
                      layoutType="FULL"
                      mode="EDIT"
                      targetRecord="{!v.newContactRecord}"
                      targetFields="{!v.contactFieldsToQuery}"
                      targetError="{!v.recordError}"
                      />
    <lightning:input label="FirstName" value="{!v.conFirstName}"/>
    <lightning:input label="LastName" value="{!v.conLastName}"/>
    <lightning:input label="Title" value="{!v.conTitle}"/>
    <lightning:input label="Department" value="{!v.conDepartment}"/>
    <lightning:button label="Add contact" onclick="{!c.addContact}"/>
</aura:component>

contactFormController.js

({
doInit: function(component, event, helper) {
         var accId=component.get("v.accountId");
         //alert("Id of Account from main comp"+accId);
        // getNewRecord loads a new record template that performs an insert when data is saved.
        component.find("creatingContactRecordOnAccount").getNewRecord(
            "Contact", // Specify Object (entityAPIName)
            null,      // recordTypeId
            false,     // skip cache?
            $A.getCallback(function() {
                var conRec = component.get("v.newContactRecord");
                var error = component.get("v.recordError");
                if(error || (conRec === null)) {
                   // alert("Error in initializing template");
                }
                else {
                    //alert("Template initialize succesfully");
                }
            })
        );
    },
    addContact: function(component, event, helper) {
        var lastName=component.get("v.conLastName");
        var firstName=component.get("v.conFirstName");
        var conTitle=component.get("v.conTitle");
        var conDepartment=component.get("v.conDepartment");
        //alert('Name is'+lastName);
        component.set("v.contactFieldsToQuery.AccountId", component.get("v.accountId"));
        component.set("v.contactFieldsToQuery.LastName",lastName);
        component.set("v.contactFieldsToQuery.Title",conTitle);
        component.set("v.contactFieldsToQuery.Department",conDepartment);
        component.find("creatingContactRecordOnAccount").saveRecord(function(saveResult) {
       
           // Handling state of response(SUCCESS,INCOMPLETE,ERROR)
       
             if (saveResult.state === "SUCCESS" || saveResult.state === "DRAFT") {
                var toastEvent = $A.get("e.force:showToast");
        toastEvent.setParams({
            title : 'Success',
            message: 'Contact Inserted Successfully',
            type: 'success'
        });
        toastEvent.fire();
            }
            else if (saveResult.state === "INCOMPLETE" ) {
                alert("Error in saving record");
            }
            else if (saveResult.state === "ERROR") {
               alert("Problem saving record, error:" +
                           JSON.stringify(saveResult.error));
            }
            else
            {
                 //alert('Unknown problem, state: ' + saveResult.state + ', error: ' + JSON.stringify(saveResult.error));
            }
       
         });
    }
})


customContactApex.apxc

public class customContactApex {
    @AuraEnabled
    public static list<contact> getAllContact(string accId)
    {
        system.debug('accId'+accId);
        List<contact> conList=new List<contact>();
        //List<contact> conListToReturn=new List<contact>();
        for(contact obj:[Select id,name,title,email,phone from contact where accountid=:accId])
        {
            conList.add(obj);
        }
     
          return conList;
     
     
    }
}




TAGS:

Custom Lightning Components for Specific Related Lists,create custom related list lightning component,lightning component to display related list records,how to create custom related list in salesforce lightning,custom related list component

4 comments:

  1. Hi i have one question , if we want the same standard functionality of related list New button on custom component New button ,so in that case will it be done with lightning:recordform insted of force:recordData

    ReplyDelete
  2. Hi, I am to build two objects and have master details relationship between them. Suppose quote (master object) and quote line item(child object) are two custom objects. The assignment looks like this -

    "Create a generalized related list component in aura which should display related records for a object. For eg : Quote is parent object and Quote Line Item is child object. When we open quote record it should display all related Quote line items under one tab. The record should be editable using Edit link."

    Can you help me to understand what and how to do this?

    ReplyDelete
  3. $A.get('e.force:refreshView').fire(); does not work after saving record.
    I am facing this problem but still haven't been solved.
    Can you suggest some solutions for this ?

    ReplyDelete