3

I have a lightning-datatable component within a custom lwc component (lets call it child), and that component sits within another component we'll call parent.

There is a Next button in the parent component which I need to disable if the user edits a value in the table within the child component.

Using oncellchange we can detect when the user makes a change to a value using inline-editing, and currently this is firing an event from the child to the parent to let the parent know the table is in 'edit mode'. However a major limitation of this is that it only seems to fire when the user clicks away from the inline-edit input field (blur). This causes a problem for me because if the user edits a value in the table and then immediately clicks the Next button without first clicking anything else, the onclick action of the Next button fires before the oncellchange event has fired in the table and I can't stop the user navigating to the next page before they may have saved or cancelled their changes, or dealt with any errors the save might throw up.

Can anybody think of a good way to solve this? In theory you could detect when the edit components are visible within the table but in reality this isn't possible because the inner workings of standard components are encapsulated so querySelector returns nothing if you try to retrieve their unique classes. I have tried manually triggering a click event on some other component when the user clicks the Next button - in order to try and get the oncellchange event to fire in the table - but it didn't work.

Thanks in advance for any help!

3

Update: This answer describes how to use the keyboard events to solve the problem. However, as pointed out by @ministe2003 in the comment, onchange event seems to work too and the below mentioned solution can be used with onchange event instead of onkeyup event.


Standard DOM keyboard events such as onkeyup, onkeydown & onkeypress seem to work in lightning-datatable, although this has not be explicitly documented in the LWC developer guide (or the Component Reference).

I don't know if there was a specific reason why Salesforce chose to leave out these events in their documentation or if they may (or may not) be supported in future or if they might not work consistently as expected. I've only tried them in the Lightning playground and they worked fine. So, I'm going to assume that it should work fine in an actual SF org too. I would encourage you to adopt this at your discretion and to perform a thorough testing to ensure it works properly.

In the HTML file of the child component, define the key event, as shown in the sample snippet below:

<lightning-datatable
        key-field="id"
        data={data}
        columns={columns} 
        onkeyup={handleKeyUp}>
</lightning-datatable>

And, the corresponding JS method code snippet should something like this:

handleKeyUp(event){
    // Write additional code to identify the key pressed from the key code, if required
    constant tableEditedEvent = new CustomEvent('tableedit');
    this.dispatchEvent(tableEditedEvent);
}

In the parent component, handle the ontableedit event and disable the appropriate button element.

This may not be the best possible solution (with good user experience), but in lack of better in-built alternatives with lightning-datatable, this should get your work done. You will have to get a bit creative in writing code to identify the key pressed (by key code) and avoid disabling the parent component button, when not needed. Additionally, if the user edited a cell and reverted the changes immediately before moving the focus from the current cell, the parent component button would already be disabled by the custom event dispatched by keyUp event handler. So, you will have to write code in the oncellchange event handler to check if no changes are found in the draftValues property (and/or additional custom properties) and re-enable the parent component button. This piece of code will execute only after the user clicks on the disabled button or elsewhere on the web page, but will re-enable the button immediately. This would become a minor or major inconvenience to user, depending on how business looks at this. You could provide alternatives like a checkbox (with label as No change in data - Enable the button) and educate user to click the checkbox, when needed.

2
  • 2
    Excellent, thanks. I never considered undocumented standard events. Turns out the standard onchange event fires as soon as any change is made with inline-editing, which is easier than onkeyup because I don't need to worry about detecting which key is pressed. The solution I've ended up with is; onchange, dispatch an event to Parent to tell it the table's in edit mode, then I've written a function within oncellchange to build a list of actual changes. If there are none then Parent is told editing has finished, otherwise the user must save or cancel their changes. Thanks for the help! – ministe2003 Dec 18 '20 at 11:47
  • 2
    I did try onchange event before posting the answer, but it didn't work for me at that time. So, I must have made some trivial code mistake or the event didn't work as expected in the Lightning playground. It was pretty late into my night, when I was trying this out and posted the answer. Thanks for comment about the onchange event. I'll update the answer, so that anybody looking for a similar problem would benefit. – arut Dec 18 '20 at 15:12

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.