Sample code:
HTML:
<template>
<lightning-card title={titleWithCount} icon-name="standard:record">
<lightning-button label="New" slot="actions" onclick={createNew}></lightning-button>
<div slot="footer">
<div if:true={countBool}>
<lightning-button label="View All" onclick={navigateToRelatedList}></lightning-button>
</div>
</div>
<div class="slds-m-around_medium">
<div if:true={listRecords}>
<template for:each={listRecords} for:item="rec">
<div key={rec.Id} class="slds-box">
<lightning-record-view-form record-id={rec.Id} object-api-name={objectName}>
<div class="slds-grid">
<div class="slds-col slds-size_1-of-2">
<lightning-output-field field-name={field1}></lightning-output-field>
<lightning-output-field field-name={field2}></lightning-output-field>
</div>
<div class="slds-col slds-size_1-of-2">
<lightning-output-field field-name={field3}></lightning-output-field>
<lightning-output-field field-name={field4}></lightning-output-field>
</div>
</div>
</lightning-record-view-form><br/><br/>
</div>
</template>
</div>
</div>
</lightning-card>
</template>
JavaScript:
import { LightningElement, api, wire, track } from 'lwc';
import fetchRecords from '@salesforce/apex/RelatedListController.fetchRecords';
import { NavigationMixin } from 'lightning/navigation';
export default class RelatedList extends NavigationMixin( LightningElement ) {
@api objectName;
@api parentObjectName;
@api fieldName;
@api fieldValue;
@api parentFieldAPIName;
@api recordId;
@api strTitle;
@api filterType;
@api operator;
@api fieldsList;
@api relationshipApiName;
@track field1;
@track field2;
@track field3;
@track field4;
@track listRecords;
@track titleWithCount;
@track countBool = false;
connectedCallback() {
var listFields = this.fieldsList.split( ',' );
console.log( 'Fields are ' + listFields );
this.field1 = listFields[ 0 ].trim();
this.field2 = listFields[ 1 ].trim();
this.field3 = listFields[ 2 ].trim();
this.field4 = listFields[ 3 ].trim();
console.log( 'Field 1 is ' + this.field1 );
console.log( 'Field 2 is ' + this.field2 );
console.log( 'Field 3 is ' + this.field3 );
console.log( 'Field 4 is ' + this.field4 );
}
get vals() {
return this.recordId + '-' + this.objectName + '-' +
this.parentFieldAPIName + '-' + this.fieldName + '-' +
this.fieldValue + '-' + this.filterType + '-' + this.operator + '-' + this.fieldsList;
}
@wire(fetchRecords, { listValues: '$vals' })
accountData( { error, data } ) {
if ( data ) {
this.listRecords = data.listRecords;
if ( data.recordCount ) {
if ( data.recordCount > 3 ) {
this.titleWithCount = this.strTitle + '(3+)';
this.countBool = true;
} else {
this.countBool = false;
this.titleWithCount = this.strTitle + '(' + data.recordCount + ')';
}
}
}
}
createNew() {
this[NavigationMixin.Navigate]({
type: 'standard__objectPage',
attributes: {
objectApiName: this.objectName,
actionName: 'new'
}
});
}
navigateToRelatedList() {
this[NavigationMixin.Navigate]({
type: 'standard__recordRelationshipPage',
attributes: {
recordId: this.recordId,
objectApiName: this.parentObjectName,
relationshipApiName: this.relationshipApiName,
actionName: 'view'
}
});
}
}
js-meta.xml:
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata" fqn="RelatedList">
<apiVersion>48.0</apiVersion>
<isExposed>true</isExposed>
<targets>
<target>lightning__RecordPage</target>
</targets>
<targetConfigs>
<targetConfig targets="lightning__RecordPage">
<property name="strTitle" type="String" label="Title" description="Enter the title"/>
<property name="objectName" type="String" label="Object Name" description="Enter the object name"/>
<property name="parentObjectName" type="String" label="Parent Object Name" description="Enter the parent object name"/>
<property name="relationshipApiName" type="String" label="Relationship Name" description="Enter the relationship API name"/>
<property name="parentFieldAPIName" type="String" label="Parent Field API Name" description="Enter the parent field API Name"/>
<property name="fieldName" type="String" label="Field Name" description="Enter the field name"/>
<property name="fieldValue" type="String" label="Field Value" description="Enter the field value"/>
<property name="filterType" type="String" label="Filter Type" description="Enter the filter type"/>
<property name="operator" type="String" label="Operator" description="Enter the operator"/>
<property name="fieldsList" type="String" label="Fields List" description="Enter the field API names separated by coma. Do not enter more than 4 fields"/>
</targetConfig>
</targetConfigs>
</LightningComponentBundle>
Apex Class:
public class RelatedListController {
@AuraEnabled( cacheable=true )
public static RelatedListWrapper fetchRecords( String listValues ) {
system.debug( 'values are ' + listValues );
List < String > strList = listValues.split( '-' );
system.debug( 'values are ' + strList );
RelatedListWrapper objWrap = new RelatedListWrapper();
if ( strList.size() == 8 ) {
String recordId = strList.get( 0 );
String objectName = strList.get( 1 );
String parentFieldAPIName = strList.get( 2 );
String fieldName = strList.get( 3 );
String fieldValue = strList.get( 4 );
String filterType = strList.get( 5 );
String operator = strList.get( 6 );
String fieldsList = strList.get( 7 );
String strSOQL = 'SELECT Id';
strSOQL += ', ' + fieldsList;
String filter = ' FROM ' + objectName + ' WHERE ' + parentFieldAPIName + ' = \'' + recordId + '\' AND ';
if ( filterType == 'String' )
filter += fieldName + ' = \'' + fieldValue + '\'';
else if ( filterType == 'Boolean' )
filter += fieldName + ' = ' + fieldValue;
else
filter += fieldName + ' ' + operator + ' ' + fieldValue;
String strCountSOQL = ' SELECT COUNT() ' + filter;
objWrap.recordCount = Database.countQuery( strCountSOQL );
strSOQL += filter + ' LIMIT 3';
objWrap.listRecords = Database.query( strSOQL );
}
return objWrap;
}
public class RelatedListWrapper {
@AuraEnabled
public List < SObject > listRecords;
@AuraEnabled
public Integer recordCount;
}
}
Output: