Efficiently handle the row action event on table in lwc through event bubbling and propagation.
KUMAR RAHUL
Tech Lead(Salesforce) at Tech Mahindra | 4X Certified | Lwc | Integration | Apex | Flows
Hello everyone, I hope everyone is safe and happy. In today's blog we are going to see a simple case and how to improve it.
So the use case is , we have table and for each row there is action ( button ) associated to it and with row-action we need to do some processing of data.
So the usual solution is , attach an event handler to the action element. For example of we have button(show Rank) placed for each row we can attach an onclick listener / handler there which will process or do something with data of the selected row. But the issue is if there are 5 such rows , then you are attaching 5 listener, if you would have 100 such rows you would be attaching 100 such listeners. So this would solve the problem but can we optimize this code?
?<table >
? ? ? ? ? ? <tr>
? ? ? ? ? ? ? <th>Index</th>
? ? ? ? ? ? ? <th>State</th>
? ? ? ? ? ? ? <th></th>
? ? ? ? ? ? </tr>
? ? ? ? ? ?<template for:each={data} for:item="item">
? ? ? ? ? ? <tr key={item.id}>
? ? ? ? ? ? ? ? <td>{item.id}</td>
? ? ? ? ? ? ? ? <td>{item.state}</td>
? ? ? ? ? ? ? ? <td> <lightning-button ?data-record = {item.id} variant="brand" label="showRank" onclick={handleClick}></lightning-button></td>
? ? ? ? ? ? </tr>
? ? ? ? ? ?</template>
? ? ? ? </table>
There is one way , instead of attaching onclick listener to every row , we can attach it to the top level element ( in our case it is table ) so that whenever any event propagated as a result of click will try to cross the table it will be intercepted there . so for this we just need to move our listener to at table level.
领英推荐
<template>
? ? <lightning-card title="Event handling for row action">
? ? ? ? <table onclick={handleClick}>
? ? ? ? ? ? <tr>
? ? ? ? ? ? ? <th>Index</th>
? ? ? ? ? ? ? <th>State</th>
? ? ? ? ? ? ? <th></th>
? ? ? ? ? ? </tr>
? ? ? ? ? ?<template for:each={data} for:item="item">
? ? ? ? ? ? <tr key={item.id}>
? ? ? ? ? ? ? ? <td>{item.id}</td>
? ? ? ? ? ? ? ? <td>{item.state}</td>
? ? ? ? ? ? ? ? <td> <lightning-button ?data-record = {item.id} variant="brand" label="showRank"></lightning-button></td>
? ? ? ? ? ? </tr>
? ? ? ? ? ?</template>
? ? ? ? </table>
? ? </lightning-card>
? ?
</template>
Now , there is only one listener is there and it is at table level. let's check the controller for this template:
import { LightningElement ,track } from 'lwc'
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
export default class EffiecientDataTable extends LightningElement {
? ?@track data = [];
? ?constructor(){
? ? ? super();
? ?}
? ?connectedCallback(){
? ? ?for(let i = 0; i < 5 ; i ++){
? ? ? ? this.data.push({id:i,state:'state'+i});
? ? ?}
? ? ?console.log(this.data);
? ?}
? ?handleClick(e){
? ? if(e.target.dataset.record){
? ? ? ? const state = this.data[e.target.dataset.record].state;
? ? ? ? const event = new ShowToastEvent({
? ? ? ? ? ? title: 'Toast message',
? ? ? ? ? ? message: state + ' is selected .',
? ? ? ? ? ? variant: 'success',
? ? ? ? ? ? mode: 'dismissable'
? ? ? ? });
? ? ? ? this.dispatchEvent(event);
? ? }
? ?
? ?}
};
CSS:
table
? ? font-family: arial, sans-serif;
? ? border-collapse: collapse;
? ? width: 100%;
? }
?
? td, th {
? ? border: 1px solid #dddddd;
? ? text-align: left;
? ? padding: 8px;
? }
?
? tr:nth-child(even) {
? ? background-color: #dddddd;
? }{
So we have just solve this issue in one of the improved way. Thankyou for reading this blog post. Let's meet in some other blog. Till then happy programming.