Lightning Component To Display Images Of Related Records | Salesforce Lightning
Lightning Component To Display Images Of Related Records
Hello Everyone, Welcome back to lightning component series. In this episode, we will learn how to display Images in lightning component and also how we can display images based on related records.
So let's begin, Before jumping into coding we will first discuss about the schema used in to create this lightning component.
Step 1 :
Schema :
In this practical, we are going to display car brands and it's related car models.
Objects :
So I have 2 related objects here Brand and Model
with API names Brand__c and Model__c.
Fields and relationships :
Brand__c : Brand Name (Name) [Standard Field]
Model__c : Model Name (Name) [Standard Field],Brand (Brand__c) [Master-Detail]
So as you can guess now Brand is the parent object and Model is a child object with the master-detail relationship.
STEP 2 :
Now must have images in both objects right ?? For that, we will use standard Files Object whose API is (ContentDocument).
So, please add files in related list of Brand and Model Object from page layout and remove unnecessary related lists.
And then create some car Brand and respective Models records with a name like :
Brand Records :
1. Ford
2. BMW
3. Volkswagen
4. Honda
Model Records under Brand(Parent) :
Ford :
1. Mustang
2. Figo
3. EcoSport
BMW :
1. BMW X5
2. BMW Z4
3. BMW 7
4. BMW X1
Volkswagen :
1. Polo
2. Vento
3. Beetle
4. Passat
Honda :
1. Honda City
2. Honda Civic
3. Honda Jazz
Once you created these records open any record and check to verify the page layout with this :
STEP 3 :
Upload relevant pictures at least one in each brand and it's model from Files section in the related list.
STEP 4 :
Now we have all the objects, fields and at least one picture in Files related list.
Now It's a perfect time to start building our lightning component.
Navigation :
Go to Developer Console -> Lightning Component -> New
So we are going to create 2 lightning components :
1. DisplayRelatedPictures.cmp : used to display the main screen
2. DisplayPictures.cmp (Child): used to display pictures only
3. DisplayRelatedController.apxc (Controller) : create apex controller with same name. This will be the server-side controller. Common for both 1 and 2 component.
STEP 5 :
So let's begin :
Follow the below code and read description comments inside code carefully to understand the code completely 😊
Follow the below code and read description comments inside code carefully to understand the code completely 😊
Component 1 : DisplayRelatedPictures.cmp
==========================================
<aura:component controller="DisplayRelatedController" implements="lightning:actionOverride,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:lightningQuickAction,force:hasRecordId,force:appHostable,flexipage:availableForAllPageTypes">
<!-- Attribute list [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]-->
<aura:attribute name="isFirst" type="boolean" default="true"/>
<aura:attribute name="isSecond" type="boolean" default="false"/>
<aura:attribute name="recordId" type="String" />
<aura:attribute name="brandList" type="List"/>
<aura:attribute name="modelList" type="List"/>
<aura:attribute name="selectedId" type="Id"/>
<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
<aura:if isTrue = "{!v.isFirst}">
<!-- Container from slds to display image on tile [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]-->
<div class="c-container" >
<lightning:layout multipleRows="true">
<aura:iteration items="{!v.brandList}" var="blist">
<lightning:layoutItem flexibility="auto" size="3" padding="around-small">
<div >
<ul class="slds-has-dividers_around-space">
<p align="justify">
<figure class="slds-image slds-image--card">
<h3 class="slds-tile__title slds-truncate" title="{!blist.Name}">
<a href="javascript:void(0);" label="{!blist.Name}">
<!-- Onclick event used inside <Div> tag so to capture the Picture OnClick event [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]-->
<div onclick = "{!c.onPictureClick}" title = "{!blist.Id}" label="{!blist.Name}">
<!-- Second Lightning Component to display the picture [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]-->
<!-- Attribute sending inside DisplayPictures event is pictureList and sObjectname [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]-->
<c:DisplayPictures pictureList="{!blist}" sObjectName="Brand__c"/>
</div>
</a>
</h3>
</figure>
</p>
</ul>
</div>
</lightning:layoutItem>
</aura:iteration>
</lightning:layout>
</div>
</aura:if>
<aura:if isTrue = "{!v.isSecond}">
<lightning:button variant="brand" label="Back" title="Back" onclick="{!c.backClick }" />
<!-- Container from slds to display image on tile [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]-->
<div class="c-container" >
<lightning:layout multipleRows="true">
<aura:iteration items="{!v.modelList}" var="blist">
<lightning:layoutItem flexibility="auto" size="3" padding="around-small">
<div class="" >
<ul class="slds-has-dividers_around-space">
<p align="justify">
<figure class="slds-image slds-image--card">
<h3 class="slds-tile__title slds-truncate" title="{!blist.Name}">
<a href="javascript:void(0);" label="{!blist.Name}">
<!-- Onclick event used inside <Div> tag so to capture the Picture OnClick event [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]-->
<div title = "{!blist.Id}" label="{!blist.Name}">
<!-- Second Lightning Component to display the picture [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]-->
<!-- Attribute sending inside DisplayPictures event is pictureList and sObjectname [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]-->
<c:DisplayPictures pictureList="{!blist}" sObjectName="Model__c"/>
</div>
</a>
</h3>
</figure>
</p>
</ul>
</div>
</lightning:layoutItem>
</aura:iteration>
</lightning:layout>
</div>
</aura:if>
</aura:component>
==========================================
Component 1 Controller : DisplayRelatedPicturesController.js
==========================================
Component 2 : DisplayPictures.cmp
==========================================
<aura:component implements="force:hasRecordId,force:lightningQuickAction" controller="DisplayRelatedController">
<!--Aura handler to handle doin it action [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]-->
<aura:handler name="init" value="{!this}" action="{!c.doInit}" />
<!-- Aura Attributes [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]-->
<aura:attribute name="pictureList" type="List"/>
<aura:attribute name="contents" type="List" default="[]"/>
<aura:attribute name="sObjectName" type="String"/>
<!-- Below default value is the URL [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]-->
<aura:attribute name="prefixURL" type="String" default="/sfc/servlet.shepherd/version/download/"/>
<!-- Below line will Iterate all contents list [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]-->
<aura:iteration items="{!v.contents}" var="content">
<figure class="slds-image slds-image--card">
<a href="javascript:void(0);" class="slds-image__crop slds-image__crop--16-by-9">
<!--Below line will display the image by putting content id [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]-->
<img src="{!v.prefixURL + content.Id}" alt="Description of the image"/>
</a>
<!-- Below code is use to provide caption to the image [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]-->
<figcaption class="slds-image__title slds-image__title--card">
<!--below line will display the Name from pictureList [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]-->
<span class="slds-image__text slds-truncate" title="Image Title"> {!v.pictureList.Name}
</span>
</figcaption>
</figure>
</aura:iteration>
</aura:component>
==========================================
Component 2 .Js : DisplayPictures.Js
==========================================
({
doInit : function(cmp){
//Below line will call getContents method from controller [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]
var action = cmp.get("c.getContents");
//Below v.pictureList is list recieved from first component [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]
var picId = cmp.get("v.pictureList");
var sObjectName = cmp.get("v.sObjectName");
//Below line will set the brandId and SObject name to pass as a parameter to the method [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]
action.setParams({
brandId : picId.Id,
ObjectName : sObjectName
})
action.setCallback(this, function(response) {
var state = response.getState();
if(cmp.isValid() && state === 'SUCCESS') {
//If the response is success then below line will set that list to "v.contents" list [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]
cmp.set("v.contents", response.getReturnValue());
}
});
$A.enqueueAction(action);
},
})
==========================================
Component 2 CSS : DisplayPictures.css
==========================================
.THIS .slds-image__crop img,.THIS .slds-file__crop img{
max-width: 100px;
}
.THIS.slds-image_card,.THIS.slds-image--card,.THIS.slds-file_card,.THIS.slds-file--card{
border-top-right-radius: 8px !important;
border-top-left-radius: 8px !important;
border: 1px solid rgb(0, 0, 0, 0);
}
==========================================
You need to create apex controller which is common for both the component
Developer Console -> Apex Class -> New
Apex Controller : DisplayRelatedController.apxc
==========================================
public class DisplayRelatedController {
//Below method will return list of brands [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]
@AuraEnabled
public static List<Brand__c> getBrand(){
List<Brand__c> proplist = [Select Id, Name FROM Brand__c];
return proplist;
}
//Below method will retun list of models [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]
@AuraEnabled
public static List<Model__c> getModel(String propId)
{
List<Model__c> unitList =[Select Id, Name,Brand__c FROM Model__c where Brand__c =: propId];
return unitList;
}
//Below method will return pictures based on Objects [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]
@AuraEnabled
public static List<ContentVersion> getContents(string brandId, string ObjectName) {
Set<Id> contentIds = new Set<Id>();
if(ObjectName == 'Brand__c')
{
//SOQL query to get pictures from Brand object [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]
for (ContentDocumentLink cont :[SELECT ContentDocumentId, LinkedEntityId FROM ContentDocumentLink where LinkedEntityId in ( SELECT Id FROM Brand__c where Id =: brandId) and LinkedEntity.Type=:ObjectName]) {
contentIds.add(cont.ContentDocumentId);
}
}
else
{
//SOQL query to get pictures from Model Object [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]
for (ContentDocumentLink cont :[SELECT ContentDocumentId, LinkedEntityId FROM ContentDocumentLink where LinkedEntityId in ( SELECT Id FROM Model__c where Id =: brandId) and LinkedEntity.Type=:ObjectName])
{
contentIds.add(cont.ContentDocumentId);
}
}
//Below Query will return the latest image Id uploaded in files [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]
return [SELECT Id,Title FROM ContentVersion WHERE ContentDocumentId IN :contentIds LIMIT 1];
}
}
==========================================
Output :
==========================================
:::::::::::::::::::::: Now select any brand Image ::::::::::::::::::
I am selecting Ford
==========================================
Coool !! In this way, you can display your related records as well as its attached images on a lightning component.
<!-- Attribute list [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]-->
<aura:attribute name="isFirst" type="boolean" default="true"/>
<aura:attribute name="isSecond" type="boolean" default="false"/>
<aura:attribute name="recordId" type="String" />
<aura:attribute name="brandList" type="List"/>
<aura:attribute name="modelList" type="List"/>
<aura:attribute name="selectedId" type="Id"/>
<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
<aura:if isTrue = "{!v.isFirst}">
<!-- Container from slds to display image on tile [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]-->
<div class="c-container" >
<lightning:layout multipleRows="true">
<aura:iteration items="{!v.brandList}" var="blist">
<lightning:layoutItem flexibility="auto" size="3" padding="around-small">
<div >
<ul class="slds-has-dividers_around-space">
<p align="justify">
<figure class="slds-image slds-image--card">
<h3 class="slds-tile__title slds-truncate" title="{!blist.Name}">
<a href="javascript:void(0);" label="{!blist.Name}">
<!-- Onclick event used inside <Div> tag so to capture the Picture OnClick event [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]-->
<div onclick = "{!c.onPictureClick}" title = "{!blist.Id}" label="{!blist.Name}">
<!-- Second Lightning Component to display the picture [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]-->
<!-- Attribute sending inside DisplayPictures event is pictureList and sObjectname [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]-->
<c:DisplayPictures pictureList="{!blist}" sObjectName="Brand__c"/>
</div>
</a>
</h3>
</figure>
</p>
</ul>
</div>
</lightning:layoutItem>
</aura:iteration>
</lightning:layout>
</div>
</aura:if>
<aura:if isTrue = "{!v.isSecond}">
<lightning:button variant="brand" label="Back" title="Back" onclick="{!c.backClick }" />
<!-- Container from slds to display image on tile [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]-->
<div class="c-container" >
<lightning:layout multipleRows="true">
<aura:iteration items="{!v.modelList}" var="blist">
<lightning:layoutItem flexibility="auto" size="3" padding="around-small">
<div class="" >
<ul class="slds-has-dividers_around-space">
<p align="justify">
<figure class="slds-image slds-image--card">
<h3 class="slds-tile__title slds-truncate" title="{!blist.Name}">
<a href="javascript:void(0);" label="{!blist.Name}">
<!-- Onclick event used inside <Div> tag so to capture the Picture OnClick event [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]-->
<div title = "{!blist.Id}" label="{!blist.Name}">
<!-- Second Lightning Component to display the picture [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]-->
<!-- Attribute sending inside DisplayPictures event is pictureList and sObjectname [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]-->
<c:DisplayPictures pictureList="{!blist}" sObjectName="Model__c"/>
</div>
</a>
</h3>
</figure>
</p>
</ul>
</div>
</lightning:layoutItem>
</aura:iteration>
</lightning:layout>
</div>
</aura:if>
</aura:component>
==========================================
Component 1 Controller : DisplayRelatedPicturesController.js
==========================================
({
doInit : function(component, event, helper) {
//Call Server Side Controller method c.getBrand [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]
var action = component.get("c.getBrand");
action.setCallback(this, function(response) {
var state = response.getState();
if (state === "SUCCESS") {
var finalBrandList = response.getReturnValue();
//set the total brands available and set to brandList [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]
component.set("v.brandList",finalBrandList);
}
});
$A.enqueueAction(action);
},
onPictureClick: function(component, event, helper) {
//get the user onclick event and the selected record id [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]
var createRecordEvent = $A.get("e.force:onPictureClick");
var selectedRecord = event.currentTarget;
var propId = selectedRecord.getAttribute("title");
var action = component.get("c.getModel");
//Set the selected Id and pass to server side controller as a parameter [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]
action.setParams({
propId : propId
})
action.setCallback(this, function(response) {
var state = response.getState();
if (state === "SUCCESS") {
var finalModelList = response.getReturnValue();
component.set("v.modelList", finalModelList);
//set first screen false and second screen on to display related moodels on second screen [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]
component.set("v.isFirst", false);
component.set("v.isSecond", true);
}
});
$A.enqueueAction(action);
},
backClick : function(component, event, helper) {
component.set("v.isFirst", true);
component.set("v.isSecond", false);
}
})
==========================================Component 2 : DisplayPictures.cmp
==========================================
<aura:component implements="force:hasRecordId,force:lightningQuickAction" controller="DisplayRelatedController">
<!--Aura handler to handle doin it action [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]-->
<aura:handler name="init" value="{!this}" action="{!c.doInit}" />
<!-- Aura Attributes [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]-->
<aura:attribute name="pictureList" type="List"/>
<aura:attribute name="contents" type="List" default="[]"/>
<aura:attribute name="sObjectName" type="String"/>
<!-- Below default value is the URL [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]-->
<aura:attribute name="prefixURL" type="String" default="/sfc/servlet.shepherd/version/download/"/>
<!-- Below line will Iterate all contents list [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]-->
<aura:iteration items="{!v.contents}" var="content">
<figure class="slds-image slds-image--card">
<a href="javascript:void(0);" class="slds-image__crop slds-image__crop--16-by-9">
<!--Below line will display the image by putting content id [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]-->
<img src="{!v.prefixURL + content.Id}" alt="Description of the image"/>
</a>
<!-- Below code is use to provide caption to the image [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]-->
<figcaption class="slds-image__title slds-image__title--card">
<!--below line will display the Name from pictureList [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]-->
<span class="slds-image__text slds-truncate" title="Image Title"> {!v.pictureList.Name}
</span>
</figcaption>
</figure>
</aura:iteration>
</aura:component>
==========================================
Component 2 .Js : DisplayPictures.Js
==========================================
({
doInit : function(cmp){
//Below line will call getContents method from controller [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]
var action = cmp.get("c.getContents");
//Below v.pictureList is list recieved from first component [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]
var picId = cmp.get("v.pictureList");
var sObjectName = cmp.get("v.sObjectName");
//Below line will set the brandId and SObject name to pass as a parameter to the method [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]
action.setParams({
brandId : picId.Id,
ObjectName : sObjectName
})
action.setCallback(this, function(response) {
var state = response.getState();
if(cmp.isValid() && state === 'SUCCESS') {
//If the response is success then below line will set that list to "v.contents" list [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]
cmp.set("v.contents", response.getReturnValue());
}
});
$A.enqueueAction(action);
},
})
==========================================
Component 2 CSS : DisplayPictures.css
==========================================
.THIS .slds-image__crop img,.THIS .slds-file__crop img{
max-width: 100px;
}
.THIS.slds-image_card,.THIS.slds-image--card,.THIS.slds-file_card,.THIS.slds-file--card{
border-top-right-radius: 8px !important;
border-top-left-radius: 8px !important;
border: 1px solid rgb(0, 0, 0, 0);
}
==========================================
You need to create apex controller which is common for both the component
Developer Console -> Apex Class -> New
Apex Controller : DisplayRelatedController.apxc
==========================================
public class DisplayRelatedController {
//Below method will return list of brands [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]
@AuraEnabled
public static List<Brand__c> getBrand(){
List<Brand__c> proplist = [Select Id, Name FROM Brand__c];
return proplist;
}
//Below method will retun list of models [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]
@AuraEnabled
public static List<Model__c> getModel(String propId)
{
List<Model__c> unitList =[Select Id, Name,Brand__c FROM Model__c where Brand__c =: propId];
return unitList;
}
//Below method will return pictures based on Objects [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]
@AuraEnabled
public static List<ContentVersion> getContents(string brandId, string ObjectName) {
Set<Id> contentIds = new Set<Id>();
if(ObjectName == 'Brand__c')
{
//SOQL query to get pictures from Brand object [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]
for (ContentDocumentLink cont :[SELECT ContentDocumentId, LinkedEntityId FROM ContentDocumentLink where LinkedEntityId in ( SELECT Id FROM Brand__c where Id =: brandId) and LinkedEntity.Type=:ObjectName]) {
contentIds.add(cont.ContentDocumentId);
}
}
else
{
//SOQL query to get pictures from Model Object [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]
for (ContentDocumentLink cont :[SELECT ContentDocumentId, LinkedEntityId FROM ContentDocumentLink where LinkedEntityId in ( SELECT Id FROM Model__c where Id =: brandId) and LinkedEntity.Type=:ObjectName])
{
contentIds.add(cont.ContentDocumentId);
}
}
//Below Query will return the latest image Id uploaded in files [COPYRIGHTS : SalesforceKid (www.salesforcekid.com)]
return [SELECT Id,Title FROM ContentVersion WHERE ContentDocumentId IN :contentIds LIMIT 1];
}
}
==========================================
Output :
==========================================
:::::::::::::::::::::: Now select any brand Image ::::::::::::::::::
I am selecting Ford
==========================================
Coool !! In this way, you can display your related records as well as its attached images on a lightning component.
WOHOOO !! YOU HAVE JUST CREATED LIGHTNING COMPONENT TO DISPLAY IMAGES OF RELATED RECORDS EPISODE
If you like this salesforcekid learning platform please let me know in the Comment section...Also, Share with your salesforce folks wish you all
Happy Learning ☁️⚡️ (Learn. Help. Share.) 😊
If you like this salesforcekid learning platform please let me know in the Comment section...Also, Share with your salesforce folks wish you all
Happy Learning ☁️⚡️ (Learn. Help. Share.) 😊
Lightning Component To Display Images Of Related Records | Salesforce Lightning
Reviewed by
on
Rating:
How to Creat ContentDocument files?
ReplyDeletei want to do this in lWC any help is welcomed
ReplyDelete