Table of Contents
Introduction
Have you received any requirements where you need to display some images in the standard datatable or file upload within the Standard Lightning DataTable?
In either case, in this blog post, we are going to see how we can extend the Lighting DataTable.
Requirement
Recently, I received the requirement where I have to showcase the picklist drop-down in the Lighting datatable, and also, I need to display the image in the Lighting datatable and the customer wanted to use all the standard functionality of the Lighting DataTable.
As picklist and image are not supported by the standard Lightning DataTable so we have decided to extend the functionality of DataTable in Lightning Web Component.
Steps
To extend the lightning datatable as per the above requirement, We have to follow the below steps
- Create a Lighting Web Component that will display the image based on the provided Url.
- Create a Lighting Web Component that will display the Combobox(Picklist) based on the provided values
- Create a Lightning DataTable that will extend the standard Lightning DataTable
- Create a final Lighting Web Component to display the details.
Step1 - Create Image Component
Create a Lightning Web Component and you can name it as “image” and use the below code
import { LightningElement, api } from 'lwc';
export default class Image extends LightningElement {
@api imageUrl;
@api height;
@api width;
@api alt;
}
Where
In the above JavaScript files we have created multiple @api decorated variables to accept the values for the URL and its different URLs
- imageUrl – The URL of the image that needs to be displayed in the UI
- height – The height of the image
- width – Widht of the image
- alt – The alternative text to show on the UI if the image is not being displayed.
Step2 - Create picklist Component
Create another Lightning Web Component and you can name it “combobox“. Use the below code.
import { LightningElement, api } from 'lwc';
export default class Combobox extends LightningElement {
@api name;
@api label;
@api value;
@api placeholder;
@api options;
@api index;
@api variant;
handleChange(event) {
event.preventDefault();
let value = event.target.value;
const picklist = new CustomEvent('select', {
detail: {
value: value,
index: this.index
},
bubbles: true,
composed: true,
cancelable: true
});
this.dispatchEvent(picklist);
}
}
Where
In the HTML file of our component, we have used standard combo box components and we are binding the dynamic values that we have defined as @api decorator so that we can accept the values from the parent component
handleChange is the JavaScript method that will get executed whenever a new value will be selected from the pick list values.
- @api name – The API name of the picklist field.
- @api label – The label of the Picklist field
- @api value – The current value of the Pickklist Value
- @api placeholder – The placeholder for the picklist value.
- @api options – The dropdown values will be displayed in the picklist value.
- @api index – Holds the index value if the component is being used within the for each syntax in LWC.
- @api variant – The variable of the label to show or hide it dynamically.
Step3 - Extend the Lightning DataTable in LWC
Lightning Web Component has the ability to extend the Lighting DataTable in Salesforce.
Create a new Lightning Web Component, you can name it “extentedTable“.
To extend the DataTable we need to first import the “LightningDatatable” from the “lightning/datatable” library
Then your Lightning Web component will extend LightningDatatable instead of LightningElement.
import LightningDatatable from 'lightning/datatable';
With the help of the ‘lightning/datatable’ library, we will be able to extend the DataTable without creating the custom datatable.
import { LightningElement } from 'lwc';
import LightningDatatable from 'lightning/datatable';
export default class ExtentedTable extends LightningDatatable {
}
Create a folder under the same Lightning Component “extentedTable” and the name is “templates”.
Within this template, folder create two HTML files
- image
- picklist
Use the below code for the HTML files
image component
In the above HTML file, we have used the component “image” and passed the values.
picklist component
In this HTML file, we are using the Component that we have created to develop the picklist in earlier steps.
Import the HTML templates
As we have created the template folder and HTML file. Now, let’s import those HTML files in our JavaScript Class as these templates will be used in DataTable to render the information.
Use below code for the template import.
import imageTemplate from './templates/image.html';
import picklistTemplate from './templates/picklist.html';
import imageTemplate from './templates/image.html';
import picklistTemplate from './templates/picklist.html';
Create Custom DataType for DataTable
As we have created the templates now the time is to create the custom datatype for Image and Picklist so that we can use those while creating the DataTable.
We will use static customTypes = {} JavaScript to create the custom datatype for Lighting DataTable.
Use below code for example
static customTypes = {
image: { // the name of the new datatype
template: imageTemplate, // The HTML file that will get rendered
typeAttributes: ['height', 'width', 'alt'] // the attribute of custom data type that we have created
},
picklist: {
template: picklistTemplate,
typeAttributes: ['name', 'label', 'value', 'placeholder', 'options', 'index', 'variant']
}
};
In the above code, we have created two custom datatypes image and picklist.
For both the types we are using the template name from the import.
Below is the complete JavaScript Code.
import LightningDatatable from 'lightning/datatable';
import imageTemplate from './templates/image.html';
import picklistTemplate from './templates/picklist.html';
export default class ExtentedTable extends LightningDatatable {
//Let's create the Custom Type for the different types
static customTypes = {
image: { // the name of the new datatype
template: imageTemplate, // The HTML file that will get rendered
typeAttributes: ['height', 'width', 'alt'] // the attribute of custom data type that we have created
},
picklist: {
template: picklistTemplate,
typeAttributes: ['name', 'label', 'value', 'placeholder', 'options', 'index', 'variant']
}
};
}
How to refer the custom type attributes in HTML
To refer to the typeAttributes variables in HTML we need to use the syntax below
{typeAttributes.attributeName}
For Example – If you wanted to access the name attribute of the picklist datatype then you will use the below code
{typeAttributes.value}
Step4 - Create the demo component
We are done with the setup now, let’s create the Lightning Web Component that we will use for demo purposes and we will see how to use the new datatable component.
You can name the component as per your wish.
Let’s create a component that will display the list of all accounts.
Here is the code that I have used to display the details.
Apex Class
public with sharing class AccountService {
@AuraEnabled(cacheable=true)
public static List listAccounts(){
try {
return [SELECT Id, Name, Industry, Phone FROM Account LIMIT 100];
} catch (Exception e) {
throw new AuraHandledException(e.getMessage());
}
}
}
HTML Code
If you noticed that in the HTML file, we have used our custom Lighting DataTable to display the DataTabel.
As we have extended the DataTable we will be able to use all the attributes that the standard datatable has.
import { LightningElement, track, wire } from 'lwc';
import listAccount from '@salesforce/apex/AccountService.listAccounts';
const columns = [
{ label: 'Id', fieldName: 'Id' },
{ label: 'Name', fieldName: 'Name', type: 'text' },
{ label: 'Phone', fieldName: 'Phone', type: 'phone' },
{ label: 'Industry', fieldName: 'Industry', type: 'text' }
];
export default class Datatable extends LightningElement {
@track dataList = [];
@track columnsList = columns;
@wire(listAccount)
wiredAccounts({ error, data }) {
if (data) {
this.dataList = [...data];
}
if (error) {
}
}
}
In the above JavaScript Code, we have prepared simple columns. Now, let’s prepare the column for the custom type that we have created.
The process is the same the only change we need to do is to use the type attribute value as exactly the same as what we created in the custom component and pass the values.
See the below code
{
label: 'Image', fieldName: 'imageUrl', type: 'image',
typeAttributes: {
height: 50,
width: 50,
alt: 'Panther School Image'
}
}
If you see that we have used the type as an image and passed the values using typeAttributes attribute.
Below is the column for the picklist datatype.
{
label: 'Industry', fieldName: 'Industry', type: 'picklist',
typeAttributes: {
name: 'Industry',
label: 'Industry',
placeholder: 'Select Industry',
index: 0,
variant: 'label-hidden',
options: [
{ label: 'Education', value: 'Education' },
{ label: 'Banking', value: 'Banking' },
{ label: 'Aparel', value: 'Aparel' },
{ label: 'Technology', value: 'Technology' }
]
}
}
Below is the Complete Code for JavaScript
import { LightningElement, track, wire } from 'lwc';
import listAccount from '@salesforce/apex/AccountService.listAccounts';
const columns = [
{
label: 'Link', fieldName: 'Name', type: 'link',
typeAttributes: {
recordId: {
fieldName: 'Id'
},
recordName: {
fieldName: 'Name'
},
}
},
{ label: 'Id', fieldName: 'Id' },
{ label: 'Name', fieldName: 'Name', type: 'text' },
{ label: 'Phone', fieldName: 'Phone', type: 'phone' },
{ label: 'Industry', fieldName: 'Industry', type: 'text' },
{
label: 'Image', fieldName: 'imageUrl', type: 'image',
typeAttributes: {
height: 50,
width: 50,
alt: 'Panther School Image'
}
},
{
label: 'Industry', fieldName: 'Industry', type: 'picklist', wrapText: true,
typeAttributes: {
name: 'Industry',
label: 'Industry',
placeholder: 'Select Industry',
index: 0,
variant: 'label-hidden',
options: [
{ label: 'Education', value: 'Education' },
{ label: 'Banking', value: 'Banking' },
{ label: 'Aparel', value: 'Aparel' },
{ label: 'Technology', value: 'Technology' }
]
}
}
];
export default class Datatable extends LightningElement {
@track dataList = [];
@track columnsList = columns;
@track errors;
@wire(listAccount)
wiredAccounts({ error, data }) {
if (data) {
this.dataList = data.map(item => {
return {
...item,
imageUrl: 'https://www.pantherschools.com/wp-content/uploads/2022/02/cropped-logoblack.png'
};
});
}
if (error) {
this.errors = error;
}
}
handleSelect(event) {
event.preventDefault();
let detail = event.detail;
console.log(JSON.stringify(detail));
}
}
Resources
Here are some of the resources that I have followed
- https://developer.salesforce.com/docs/component-library/bundle/lightning-combobox/specification
- https://www.pantherschools.com/how-to-develop-lightning-datatable-for-salesforce-flows/
- https://www.pantherschools.com/how-to-use-the-lookup-field-in-lightning-datatable/
- https://www.pantherschools.com/how-to-add-hyperlink-and-icons-in-lightningdatatable/