Recently, I received the requirement where I have to showcase the picklist drop-down in the Lighting datatable, and also,
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.
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.
To extend the lightning datatable as per the above requirement, We have to follow the below steps
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;
}
In the above JavaScript files we have created multiple @api decorated variables to accept the values for the URL and its different URLs
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);
}
}
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.
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
Use the below code for the HTML files
In the above HTML file, we have used the component “image” and passed the values.
In this HTML file, we are using the Component that we have created to develop the picklist in earlier steps.
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';
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']
}
};
}
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}
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.
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());
}
}
}
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));
}
}
Once you have completed the test component. Deploy all the code to Salesforce and test it.
Below is the output of our component that we have developed.
Here are some of the resources that I have followed