I am attempting to add a confirmation dialog (yes/no) for a predefined action on a LWC which does archiving. Basically need to show a popup saying do you confirm and the user selects yes/no to proceed. It seems to work but I had a question on some weird behavior. Please let me explain.
My confirm dialog LWC as follows:
<template>
<lightning-card if:true={visible}>
<div class="slds-container_small">
<section role="dialog" tabindex="-1" aria-labelledby="modal-heading-01" aria-modal="true" aria-describedby="modal-content-id-1" class="slds-modal slds-fade-in-open">
<div class="slds-modal__container">
<header class="slds-modal__header">
<h2 id="modal-heading-01" class="slds-text-heading_medium slds-hyphenate">{title}</h2>
</header>
<div class="slds-modal__content slds-p-around_medium" id="modal-content-id-1">
<p>{message}</p>
</div>
<footer class="slds-modal__footer">
<lightning-button variant="neutral"
name="cancel"
label={cancelLabel}
title={cancelLabel}
onclick={handleClick} ></lightning-button>
<lightning-button variant="brand"
name="confirm"
label={confirmLabel}
title={confirmLabel}
onclick={handleClick} ></lightning-button>
</footer>
</div>
</section>
<div class="slds-backdrop slds-backdrop_open"></div>
</div>
</lightning-card>
</template>
import { LightningElement, api } from 'lwc';
export default class ConfirmationDialog extends LightningElement {
@api visible; //used to hide/show dialog
@api title; //modal title
@api name; //reference name of the component
@api message; //modal message
@api confirmLabel; //confirm button label
@api cancelLabel; //cancel button label
@api originalMessage; //any event/message/detail to be published back to the parent component
//handles button clicks
handleClick(event){
console.log('#1 I am in handleClick in confirmationDialog.js');
let detail = {
originalMessage: this.originalMessage,
status: event.target.name
};
//dispatch a 'click' event so the parent component can handle it
this.dispatchEvent(new CustomEvent('click', {detail: detail}));
}
}
There is a parent LWC or 'manager' LWC that shows a list of rows with icons at the end that either say archive or edit or save. The icons are displayed by a child LWC called iconRenderer:
Each row on my parent LWC has a button renderer LWC that shows an icon.
<lightning-button-icon
icon-name="utility:archive"
variant="bare"
size="large"
alternative-text="Archive"
class="slds-m-left_xx-small slds-p-top_xx-small slds-p-bottom_x-small slds-p-horizontal_xxx-small icon-border"
title="Archive"
onclick={handleArchiveClick}>
</lightning-button-icon>
So when someone clicks on the archive icon the following handler happens on the icon rendered LWC:
handleArchiveClick() {
let detail = {
recordid: this.recordid,
confirmDialog: true //as I want the confirmDialog to pop up
};
this.dispatchEvent(new CustomEvent('archive', {detail: detail}));
}
Now on the parent LWC (manager) where all this happens, I have the handleArchive event handler that basically shows the confirm dialog if confirmDialog flag is set to true
handleArchive(event) {
let detail = event.detail;
if(detail.confirmDialog == true){
console.log('detail.confirmDialog is true');
this.originalMessage = JSON.stringify(event);
this.showConfirmModal = true;
}else{
console.log('******* DO ARCHIVE NOW ********');
}
I also have the following clickHandler right after the handleArchive and this is where my question is about:
handleClick(event){
if(event.detail !== 1){
console.log('Displaying event passed in handleClick');
console.log(JSON.stringify(event));
if(event.target.name === 'confirmModal'){
if(event.detail.status === 'confirm') {
let origEvent = JSON.parse(event.detail.originalMessage);
let detail = origEvent['detail'];
detail.confirmDialog = false;
// WHY DO I HAVE TO CALL THE HANDLER DIRECTLY AND WHY NOT JUST A DISPATCH EVENT OF THE SAME TYPE
this.handleArchive(new CustomEvent(origEvent['type'], {detail: detail}));
}else if(event.detail.status === 'cancel'){
console.log('cancel');
}
this.showConfirmModal = false;
//ALSO WHY DOES handleClick() GET FIRED AGAIN AFTER I CHOSE YES OR NO AND IT CLOSES THE DIALOG?
}
}
}
The 2 questions I have are:
1). Instead of
this.handleArchive(new CustomEvent(origEvent['type'], {detail: detail}))
when I do
this.dispatchEvent(new CustomEvent('archive', {detail: detail}))
how come that event does not end up getting handled by the handleArchive handler?
The only way I can get it to work is by calling the handler explicitly. Why is that?
2). When I click Yes or no, it fires a handleClick event again of detail = 1. Why is that click event happening? I have to filter it out using my if(event.detail !== 1) condition.
origEvent['type']
equal to'archive'
? What is the exact value oforigEvent['type']
? Did you try debug that?