6

By following a tutorial (How to use custom LWC lightning component in lightning-datatable) I was able to extend lightning datatable and insert a button into the final column.

Now, I am currently struggling with how I communicate property changes down through the component hierarchy in order to disable/enable this button when certain events occur in the parent. I have checked the documentation regarding this (https://developer.salesforce.com/docs/component-library/documentation/lwc/lwc.create_components_data_binding) but I can't tailor the example to get a solution to my problem.

Below is the component that implements the custom datatable with a button in one column. When the button is pressed it disables itself and dispatches an event. This component listens for that dispatched event and after executing some action (omitted for brevity), I want to communicate to the button pressed (not all buttons) to enable itself once again.

I have experimented with declaring public properties on the button using @api, and then attempting to enable/disable the button using that, but all my efforts have been fruitless so I've omitted all attempts using that approach.

Here is my implementation:

customDatatableImplementation.html

<template>
    <lightning-card title="Custom Datatable" icon-name="standard:contact">
            <c-datatable-with-freeze-unfreeze-button 
            key-field="id"
            data={data}
            columns={columns}
            onclick={handleToggleClick}
            hide-checkbox-column>
            </c-datatable-with-freeze-unfreeze-button>
    </lightning-card>
</template>

customDatatableImplementation.js

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

export default class CustomDatatable extends LightningElement {
    @api recordId;
    @track columns = [];
    @track data = [];
    @track error;
    @track toggleButtonLabel;

    constructor() {
        super();
        this.template.addEventListener('changelabelevent', this.handleCustomEvent.bind(this));
    }

    handleToggleClick(event) {

        if (this.toggleButtonLabel === 'Freeze') {
         // Do something
         // Communicate with button to enable itself again 

        } 

        else if(this.toggleButtonLabel === 'Unfreeze') {
         // Do something
        // Communicate with button to enable itself again
        }



    handleCustomEvent(event) {
        const textVal = event.detail;
        this.toggleButtonLabel = textVal;
    }

}

My datatable that uses a custom type:

datatableWithFreezeUnfreezeButton.html

<template>
    <c-datatable-with-freeze-unfreeze-button 
    key-field="id"
    data={data}
    columns={columns}
    onclick={onclick}
    hide-checkbox-column>
    </c-datatable-with-freeze-unfreeze-button>
</template>

datatableWithFreezeUnfreezeButton.js

import LightningDatatable from 'lightning/datatable';
import freezeUnfreezeButton from './freezeUnfreezeButton.html';

    export default class datatableWithFreezeUnfreezeButton extends LightningDatatable {

        static customTypes = {
            toggleButton: {
                template: freezeUnfreezeButton
            }
        };

    }

The button that is used to declare the custom type on my datatable and the one that dispatches an event up the hierarchy to customDatatableImplementation:

freezeUnfreezeButton.html

<template> <lightning-button variant="neutral" label={toggleButtonLabel} title="Toggle content action" onclick={handleToggleClick}> </lightning-button> </template>

freezeUnfreezeButton.js

import { LightningElement, track} from 'lwc';

export default class freezeUnfreezeButtonComponent extends LightningElement {
    @track toggleButtonLabel = 'Freeze Card';

    handleToggleClick() {

        // Get the buttons label. We dispatch this to the tables
        // controller in order to handle the correct event.
        const selectEvent = new CustomEvent('changelabelevent', {
            composed: true, 
            bubbles: true,
            detail: this.toggleButtonLabel
        });

        // Change the label on the button
        if (this.toggleButtonLabel === 'Freeze') {
            this.toggleButtonLabel = 'Unfreeze';
        } else {
            this.toggleButtonLabel = 'Freeze';
        }

        // Dispatch the event to the parent
        this.dispatchEvent(selectEvent);
    }

}
2

You can define typeAttributes for your custom data type.

static customTypes = {
    toggleButton: {
        template: freezeUnfreezeButton,
        typeAttributes  : ['disabled']
    }
};

Then you need to pass value for this attribute with your data.

@track columns = [
    { label: 'Name', fieldName: 'Name', type: '', typeAttributes: {
                                                      disabled: {fieldName: 'btn_status'}
                                                  }
    },
    ........
];

@track data = [
    {'Name' : 'YourName', btn_status : true, ..... },
    {'Name' : 'YourName', btn_status : false, ..... },
    ......
];

Then you can simply update your data when you need to enable or disable the button.

|improve this answer|||||
  • Is there a way to access and change the value of btn_status for a certain row without updating it along with the data? – DylanR Nov 13 '19 at 11:07
  • I am not sure whether it will work or not. You can create a public method on freezButton. Then filter it using a querySelector and invoke the method. Please try this. – Isuru Buddhika Herath Nov 13 '19 at 23:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.