[SalesForce] How to programatically add selected rows to a LWC datatable

I have an action button in a LWC datatable. One of the things I would like it to do is to 'select' the row in the datatable when it fires. I can pass in pre-selected rows but I'm not sure how to add them in the code.

testDatatable.html

<template>
    <lightning-datatable
            data={mydata}
            columns={columns}
            key-field={keyfield}
            selected-rows={preSelectedIds}
            hide-checkbox-column={hideCheckboxColumn}
            sorted-by={sortedBy}
            sorted-direction={sortedDirection}
            onsort={updateColumnSorting}
            onrowaction={handleRowAction}>
    </lightning-datatable>     
</template>

testDatatable.js

import { LightningElement, api, track  } from 'lwc';

const COLUMNS = [
    {
        label: 'Name',
        fieldName: 'Name',
        type: 'text',
        sortable: 'true',
        initialWidth: 280
    },
    {
        label: 'Button',
        type: 'button',
        typeAttributes: { 
            label: 'Select',
            name: 'select',
            title: 'Click to do something',
            disabled: { fieldName: 'buttonDisabled' },
        },
        initialWidth: 90
    },
];

const MYDATA = [
    {
        Name: '',
        Id: '',
        buttonDisabled: ''
    }
];
export default class TestDatatable extends LightningElement {

    @api tableData;
    @api columns = COLUMNS;
    @api keyfield = 'Id';
    @api hideCheckboxColumn;
    @track sortedBy;
    @track sortedDirection;
    @track mydata = MYDATA;
    @track preSelectedIds = [];

    connectedCallback() {
        // Add fields to datatable records
        console.log('Table',JSON.parse(JSON.stringify(this.tableData)));
        console.log('My',JSON.parse(JSON.stringify(this.mydata)));
        this.mydata = this.tableData.map(tableRecord => ({
            Id: tableRecord.Id,
            Name: tableRecord.Name,
            buttonDisabled: false
            })
        );
        console.log('My-after',JSON.parse(JSON.stringify(this.mydata)));
        this.hideCheckboxColumn = true;
        this.preSelectedIds.push('0016C00000Bd2yYQAR');
        this.preSelectedIds.push('0016C00000Bd2ydQAB');
    }

    handleRowAction(event) {
        const action = event.detail.action;
        const row = JSON.parse(JSON.stringify(event.detail.row));
        const keyValue = row[this.keyfield];   
        console.log('Action,Key,Row',action.name,keyValue,row);
        // Change the label and disable the button here
        this.mydata = this.mydata.map(rowData => {
            if (rowData[this.keyfield] === keyValue) {
                switch (action.name) {
                    case 'select':
                        console.log('select',rowData[this.keyfield],rowData['select']);
                        rowData.buttonDisabled = true;
                        break;
                    default:
                }                
            }
            return rowData;
        });
    }

    updateColumnSorting(event) {
        this.sortedBy = event.detail.fieldName;
        this.sortedDirection = event.detail.sortDirection;
        let fieldValue = row => row[this.sortedBy] || '';
        let reverse = this.sortedDirection === 'asc'? 1: -1;
        this.mydata = [...this.mydata.sort(
            (a,b)=>(a=fieldValue(a),b=fieldValue(b),reverse*((a>b)-(b>a)))
        )];
    }

}

Best Answer

You simply need to add the value to the list of selected values:

switch(action.name) {
    case 'select':
        let actionRow = this.mydata.find(row => rowData[this.keyfield] === keyValue);
        // Not already selected
        if(this.preSelectedIds.indexOf(actionRow[this.keyfield]) === -1) {
            this.preSelectedIds.push(actionRow[this.keyfield]);
            this.preSelectedIds = [...this.preSelectedIds];
        }
        actionRow.buttonDisabled = true;
        this.mydata = [...this.mydata];
}

Note the use of the spread syntax to duplicate the list to trigger @track and update the UI.

Related Topic