I have a custom lighting-datatable where the last row is a column that contains two buttons. When either of these buttons is pressed, I am attempting to retrieve the rowId of the row where the button was pressed.
In my attempt to retrieve the rowId I followed the code example in the section 'Creating Custom Datatypes' from this page: https://developer.salesforce.com/docs/component-library/bundle/lightning-datatable/documentation
The rowId is being returned as 'undefined' in my datatable implementation.
I have removed as much unnecessary code as I could from my implementation below. If you believe I've left something important out, please let me know.
The generalized construction of this custom datatable is like so:
myCustomDatatableImplementation.html
<template>
<lightning-card title="Account Details" icon-name="utility:money">
<c-my-custom-datatable-implementation
key-field="id"
data={data}
columns={columns}
onfirstbuttonpressed={handleFirstButtonPressed}
onsecondbuttonpressed={handleSecondButtonPressed}
hide-checkbox-column
>
</c-my-custom-datatable-implementation>
</lightning-card>
</template>
myCustomDatatableImplementation.js
import { LightningElement, track, api } from 'lwc';
export default class myCustomDatableImplementation extends LightningElement {
@track columns = columns;
@track data;
// Get the accounts
async connectedCallback() {
// retrieve and set data
}
// This handles the event dispatched from
// myTwoButtons.js when the first button is pressed
handleFirstButtonPressed(event) {
const { rowId } = event.detail;
// rowId is undefined here
}
// This handles the event dispatched from
// myTwoButtons.js when the second button is pressed
handleSecondButtonPressed(event) {
const { rowId } = event.detail;
// rowId is undefined here
}
}
customDatatable.html
<template>
<custom-datatable
key-field="id"
data={data}
columns={columns}
onclick={onclick}
hide-checkbox-column
>
</custom-datatable>
</template>
customDatatable.js
import LightningDatatable from 'lightning/datatable';
import buttons from './buttonTemplate.html';
export default class customDatatble extends LightningDatatable {
static customTypes = {
buttonsToShow: {
template: buttons,
typeAttributes: ['attr']
}
};
}
buttonTemplate.html
<template>
<c-my-two-buttons row-id={value}>
</c-my-two-buttons>
</template>
myTwoButtons.html
<template>
<div>
<lightning-button variant="neutral" title="Toggle content action" label="First Button"
onclick={handleFirstButtonPressed}>
</lightning-button>
</div>
<div>
<lightning-button variant="neutral" title="Toggle content action" label="Second Button"
onclick={handleSecondButtonPressed}>
</lightning-button>
</div>
</template>
myTwoButtons.js
import { LightningElement, track, api } from 'lwc';
export default class myTwoButtons extends LightningElement {
@api rowId;
handleFirstButtonPressed() {
const selectEvent = new CustomEvent('firstbuttonpressed', {
composed: true,
bubbles: true,
detail: {
rowId: this.rowId,
},
});
this.dispatchEvent(selectEvent);
}
handlePayeePressed() {
const selectEvent = new CustomEvent('secondbuttonpressed', {
composed: true,
bubbles: true,
detail: {
rowId: this.rowId,
},
});
this.dispatchEvent(selectEvent);
}
}
Best Answer
I ended up resolving my issue and in doing so I believe that the documentation ( https://developer.salesforce.com/docs/component-library/bundle/lightning-datatable/documentation) for 'Creating Custom Data Types' has a few errors. I have provided an explanation of one of these errors below.
I think my initial error lay in the belief that the 'value' property that's assigned to the attribute 'row-id' in buttonTemplate.html was a global property that we don't have to compute ourselves (this is the impression the documentation gave me as no value is set for in in the JavaScript). This may be the case and I may be using it wrong, but I couldn't figure out a solution. Instead, I used typeAttributes like so to assign a rowId myself.
Here is how I solved my rowId issue.
Assign row-id a value using typeAttributes:
buttonTemplate.html
Define this typeAttribute in the custom datatable:
buttonTemplate.js
Finally, wherever you use the custom datatable, set the type attribute when you're setting the data:
myCustomDatatableImplementation.js
You will now be able to dispatch the rowId up the hierarchy from the button pressed.
Now, here is why I believe the documentation may be erroneous. If I have misunderstood something, please let me know!
For example, the documentation states:
This wrapper uses the following JavaScript class:
It was my understanding that the markup must use the kebab case equivalent of it's JavaScript controller with 'c' prepended. Therefore the mark-up should be:
This is only one of the potential issues I've noticed.