Custom LWC Component in Lightning-Datatable
If you want to integrate a custom Lightning Web Component (LWC) into a lightning-datatable to add functionalities like uploading a file for each record, you can achieve this by extending the lightning-datatable and defining a custom data type. Here’s a step-by-step explanation of how you can implement this functionality.
Answer
Step 1: Create the Custom Component
First, create a custom LWC component that will handle the file upload. The component includes a lightning-file-upload element and emits an event after a file is successfully uploaded.
HTML (pocCustomComp.html):
<template>
<div>
Id: {recordId}
</div>
<lightning-file-upload label="Upload"
name="fileUploader"
accept={acceptedFormats}
record-id={recordId}
onuploadfinished={handleUploadFinished}>
</lightning-file-upload>
</template>JavaScript (pocCustomComp.js):
import { LightningElement, api } from 'lwc';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
export default class PocCustomComp extends LightningElement {
@api recordId;
@api acceptedFormats;
handleUploadFinished() {
this.dispatchEvent(new CustomEvent('uploadfinished', {
composed: true,
bubbles: true,
cancelable: true,
detail: {
data: { name: 'some data', recordId: this.recordId }
}
}));
this.dispatchEvent(new ShowToastEvent({
title: 'Completed',
message: 'File has been uploaded',
}));
}
}Explanation:
The pocCustomComp component uses the lightning-file-upload element for file uploads and emits an event after completion. It accepts recordId and acceptedFormats as inputs. Upon successful upload, it shows a toast notification and emits a custom event containing the uploaded file’s details.
Step 2: Extend the Datatable
Next, create a new component that extends the lightning-datatable to support custom data types.
JavaScript (pocLightningDatatable.js):
import LightningDatatable from 'lightning/datatable';
import pocFileUpload from './pocFileUpload.html';
export default class PocLightningDatatable extends LightningDatatable {
static customTypes = {
fileUpload: {
template: pocFileUpload,
typeAttributes: ['acceptedFormats'],
}
};
}Explanation:
The PocLightningDatatable class extends lightning-datatable and adds a custom data type called fileUpload. This data type uses the pocFileUpload.html template and accepts additional attributes like acceptedFormats.
Step 3: Define the Custom Template
Define the HTML template pocFileUpload.html to use the custom component (pocCustomComp) you created earlier.
HTML (pocFileUpload.html):
<template>
<c-poc-custom-comp record-id={value}
accepted-formats={typeAttributes.acceptedFormats}>
</c-poc-custom-comp>
</template>Explanation: The pocFileUpload.html template embeds the pocCustomComp component, passing the value (bound to the datatable’s fieldName) as recordId and the type attributes as acceptedFormats. This links the custom component to the datatable.
Step 4: Use the Custom Datatable
You can now use the extended datatable component in your application.
HTML (poc.html):
<template>
<c-poc-lightning-datatable key-field="id"
data={data}
columns={columns}
onuploadfinished={handleUploadFinished}
hide-checkbox-column>
</c-poc-lightning-datatable>
</template>JavaScript (poc.js):
import { LightningElement, track } from 'lwc';
import findAccounts from '@salesforce/apex/poc.findAccounts';
export default class Poc extends LightningElement {
@track data = [];
columns;
connectedCallback() {
this.columns = [
{ label: 'Name', fieldName: 'Name' },
{ label: 'Account Number', fieldName: 'AccountNumber' },
{ label: 'Upload', type: 'fileUpload', fieldName: 'Id', typeAttributes: { acceptedFormats: '.jpg,.jpeg,.pdf,.png' } }
];
findAccounts().then(res => { this.data = res; }).catch(err => console.error(err));
}
handleUploadFinished(event) {
event.stopPropagation();
console.log('data => ', JSON.stringify(event.detail.data));
}
}Explanation: The poc component fetches account data using an Apex method and binds it to the custom datatable. It defines a column with the custom fileUpload type and listens for the uploadfinished event to process uploaded files.
Step 5: Apex Class
The Apex class retrieves data for the datatable.
Apex (poc.cls):
public without sharing class poc {
@AuraEnabled(cacheable=true)
public static List<Account> findAccounts() {
return [SELECT Name, AccountNumber from Account LIMIT 10];
}
}Explanation: The poc Apex class fetches a list of accounts from Salesforce using a simple SOQL query. It is marked as @AuraEnabled to make it accessible from LWC components.
This complete setup enables you to use a custom LWC component as a column type in a lightning-datatable. The extended datatable integrates the custom component seamlessly, providing enhanced functionality like file uploads.
Summing Up
In this approach, I’ve demonstrated how to seamlessly integrate a custom Lightning Web Component into a lightning-datatable to enable advanced functionalities like file uploads for each record. By extending the datatable and defining a custom data type, we unlock endless possibilities for tailoring Salesforce interfaces to specific business needs. This solution not only enhances user experience but also provides a clean, reusable architecture that aligns perfectly with Salesforce’s declarative and programmatic development standards. Whether you’re building scalable solutions or aiming for innovation, this technique is a game-changer for creating dynamic and interactive data-driven components.

