I want to invoke a modal from a button click in a lightning-datatable that will display the contents of the account description (because this can sometimes be a large amount of text that renders in a sub-optimal way from a UX perspective, even with setting the lightning-datatable wrapping attribute to true).
The lightning-datatable looks like so from the below code:
and upon clicking the button, that looks like a hyperlink because of the button variant, the modal appears:
However, I want the modal to display the data from the Description field, for example 'This is account 134' if the button from the first row in the lightning-datatable was selected.
I am reviewing the docs here and here but I think I need stronger coffee to understand it better.
My code so far is below:
<template>
<lightning-card title="Account Table">
<div class="slds-m-around_medium">
<template if:true={accounts}>
<lightning-datatable
key-field="Id"
data={accounts}
columns={columns}
hide-checkbox-column="true"
onrowaction={handleOpenModal}
>
</lightning-datatable>
</template>
<template if:true={error}>
<div class="slds-text-color_error">{error}</div>
</template>
</div>
</lightning-card>
</template>
import { LightningElement, wire } from 'lwc';
import getAccountList from '@salesforce/apex/AccountDataTable.getAccountList';
import MyModal from "c/myModal";
const columns = [
{ label: 'Name', fieldName: 'Name', type: 'text' },
{ label: 'Description', fieldName: 'Description', type: 'text' },
{
label: 'Description',
type: 'button',
typeAttributes: {
label: { fieldName: 'Description' },
name: 'view_description',
title: 'Click to see the full description',
iconPosition: 'center',
variant: 'base'
}
}
];
export default class AccountTable extends LightningElement {
accounts;
error;
columns = columns;
connectedCallback() {
this.fetchAccounts();
}
fetchAccounts() {
getAccountList()
.then(result => {
this.accounts = result;
this.error = undefined;
})
.catch(error => {
this.error = error;
this.accounts = undefined;
});
}
// ...
// Process the select event from within the modal
handleSelectEvent(detail) {
const { id, value } = detail;
console.log(`select event fired elem with id ${id} and value: ${value}`);
}
// ...
// Trigger visibility of the modal
handleOpenModal() {
MyModal.open({
label: 'Modal Title',
size: 'large',
description: 'Modal Title with brief description',
// event triggered when new CustomEvent('select', {detail: {}});
// occurs *from within* LightningModal.
// see dispatchSelectEvent() in c/myModal.js above
onselect: (e) => {
// stop further propagation of the event
e.stopPropagation();
// hand off to separate function to process
// result of the event (see above in this example)
this.handleSelectEvent(e.detail);
// or proxy to be handled above by dispatching
// another custom event to pass on the event
// this.dispatchEvent(e);
}
});
}
}
<template>
<lightning-modal-header label="My Modal Heading"></lightning-modal-header>
<lightning-modal-body> Content: {content} </lightning-modal-body>
<lightning-modal-footer>
<lightning-button label="OK" onclick={handleOkay}></lightning-button>
</lightning-modal-footer>
</template>
import { api } from 'lwc';
import LightningModal from 'lightning/modal';
export default class MyModal extends LightningModal {
@api content;
handleOkay() {
this.close('okay');
}
dispatchSelectEvent(e) {
console.log('dispatchSelectEvent called' + e);
// e.target might represent an input with an id and value
const { id, value } = e.target;
const selectEvent = new CustomEvent('select', {
detail: { id, value }
});
this.dispatchEvent(selectEvent);
}
}
public with sharing class AccountDataTable {
@AuraEnabled(cacheable=true)
public static List<Account> getAccountList() {
return [SELECT Id, Name, Description FROM Account LIMIT 5];
}
}