Dynamically disable buttons inside lightning:datatable in Lightning Web Component

buttondynamicjavascriptlightning-datatablelightning-web-components

I have a lightning:datatable with two buttons for onrowaction. Datatable shows Order Items.
I want to dynamically disable ALL buttons (including "Add" and "Remove") after button "Confirm" was clicked.
When it is clicked, a callout is made and Order Status changes to "Activated", then 'disableButtons' variable, which listens to Status field, gets updated. "Confirm" button gets disabled, but "Add" and "Remove" remain enabled. Need to find the way to disable them also.

<template>
    <lightning-card title="My Order" icon-name="standard:webcart">
        <lightning-datatable
            key-field="Id"
            data={products}
            columns={columns}
            show-row-number-column
            row-number-offset={rowOffset}
            hide-checkbox-column
            onrowaction={handleQuantityChange}
        >
        </lightning-datatable>
        <lightning-button variant="brand" label="Confirm" title="Confirm Request in External System" 
                          onclick={handleConfirm} class="slds-align_absolute-center slds-p-top_small" disabled={disableButtons}></lightning-button>
    </lightning-card>
</template>

Columns:

const COLUMNS = [
{ label: 'Name', fieldName: 'Name', type: 'text' },
{ label: 'List Price', fieldName: 'UnitPrice', type: 'currency'},
{ label: 'Quantity', fieldName: 'Quantity', type: 'number' },
{ label: 'Total Price', fieldName: 'TotalPrice', type: 'currency' },
{ label: '', type: 'button', initialWidth: 75, typeAttributes: 
    {iconName: 'utility:add', label: '', name: 'Add', disabled: {disableButtons}}
},
{ label: '', type: 'button', initialWidth: 75, typeAttributes: 
    {iconName: 'utility:dash', label: '', name: 'Remove', disabled: {disableButtons}}
}

];

Controller snippets which may be needed:

_isOrderActivated;
disableButtons = true;
    
    @wire(isOrderActivated, { currentOrderId: '$recordId' })
    wireIsOrderActivated(result) {
        this._isOrderActivated = result;
        let { data, error } = result;
        if (error) {
            this.disableButtons = true;
            throw new Error('Failed to get order Status: ' + error.body.message);
        }
        else this.disableButtons = data;
    }

handleConfirm(){
        confirmOrder({currentOrderId: this.recordId})
        .then(() => {
            return refreshApex(this._isOrderActivated);
        })
        .catch(error => {
            throw new Error('Failed to confirm order: ' + error.body.message);
        })
    }

Best Answer

You need to tweak your code a bit, to make columns a JS getter instead of a constant. Inside the getter you can then assign the disableButtons property to the disabled attribute.

export default class Demo extends LightningElement {

    disableButtons = false;

    get columns(){
        return [
            { label: 'Name', fieldName: 'Name', type: 'text' },
            { label: 'List Price', fieldName: 'UnitPrice', type: 'currency'},
            { label: 'Quantity', fieldName: 'Quantity', type: 'number' },
            { label: 'Total Price', fieldName: 'TotalPrice', type: 'currency' },
            { label: '', type: 'button', initialWidth: 75, typeAttributes: 
                {iconName: 'utility:add', label: '', name: 'Add', disabled: this.disableButtons}
            },
            { label: '', type: 'button', initialWidth: 75, typeAttributes: 
                {iconName: 'utility:dash', label: '', name: 'Remove', disabled: this.disableButtons}
            }
        ];
    }

    ...

}