Step 1 : create custom component as follows.
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>
and its 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',
}));
}
}
Step 2 : Create a new component which extends datatable
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'],
}
};
}
Here we are defining custom data types – fileUpload. Also do you notice that we are importing pocFileUpload template? You need to create pocFileUpload.html in the same folder as pocLightningDatatable
pocFileUpload.html – you have to use the custom component that we created before.
<template>
<c-poc-custom-comp record-id={value}
accepted-formats={typeAttributes.acceptedFormats}>
</c-poc-custom-comp>
</template>
Observe the usage of value
here, it is automatically passed as the value for the fieldName we define in columns
.
Step 3 : We can use the component (that extended datatable) where-ever we want
<template>
<c-poc-lightning-datatable key-field="id"
data={data}
columns={columns}
onuploadfinished={handleUploadFinished}
hide-checkbox-column>
</c-poc-lightning-datatable>
</template>
And the javascript which uses custom datatype:
import { LightningElement, track } from 'lwc';
import findAccounts from '@salesforce/apex/poc.findAccounts';
export default class Poc extends LightningElement {
@track data = [];
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));
}
}
Note: pocLightningDatatable.html will not have anything in it.
Apex class:
public without sharing class poc {
@AuraEnabled(cacheable=true)
public static List<Account> findAccounts() {
return [SELECT Name, AccountNumber from Account Limit 10];
}
}
Reference: https://salesforcesas.home.blog/2019/07/26/using-custom-lwc-components-in-lightning-datatable/
Ideally you should fire event with data of record identifier (Id
field) which should be handled in parent component for fetching whole record based on passed Id
and then showing record data in modal and the modal should be implemented in parent component which will show up in this event handler.
Explanation:
just pass the Id for fieldName without typeAttributes as below:
{ label: 'DETAILS', type: 'detailsButton', fieldName: 'Id', fixedWidth: 70, cellAttributes: { alignment: "center" }}
In the custom component dispatch event with composed and bubbles as true so that it becomes API for datatable:
this.dispatchEvent(new CustomEvent('showmodal', {
detail: {
recordId: this.recordId
},
bubbles: true,
composed: true
}));
You should define @api recordId
and assign the value
to recordId in custom component template so that value comes from mentioned fieldName - which is Id
. You can refer to this example for understanding importance of value
in template.
Now in the parent component handle the event:
<c-my-datatable onshowmodal={handleShowModal}
Best Answer
You can do something like below: