1

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)))
        )];
    }

}

2 Answers 2

1

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.

1
  • Is this only replacing what I have for the Switch statement? When I do that, it only works the first time an action button is clicked. Plus it selects a different row from the one that was clicked.
    – Eric Smith
    Commented Feb 16, 2020 at 19:26
0

This ended up working ok:

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;
                    // Not already selected
                    if(this.preSelectedIds.indexOf(rowData[this.keyfield]) === -1) {
                        this.preSelectedIds.push(rowData[this.keyfield]);
                        this.preSelectedIds = [...this.preSelectedIds];
                    }
                    break;
                default:
            }                                
        }
        return rowData;
    });

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .