0

There is a stackexchange post here that is trying to make it possible for clicking outside the modal to allow the modal to close

However, I am trying to do the opposite. I have a parent component that passes data to a child component from a wire method. But whenever I click outside the modal, the modal closes and I can see a value of undefined in the console. I'm not sure where this value is coming from since I removed all console.logs from my code to see if it was being generated somewhere else. Is there a property or a value in the LWC design system that you must include/exclude in order prevent this behavior?

I pulled this code from the following article; this is much cleaner than my implementation and the code he is using I just tested and it is still closing the modal when they click outside the modal.

HTML - Child Confirmation

<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>

JS Child Confirmation

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){
        //creates object which will be published to the parent component
        let finalEvent = {
            originalMessage: this.originalMessage,
            status: event.target.name
        };

        //dispatch a 'click' event so the parent component can handle it
        this.dispatchEvent(new CustomEvent('click', {detail: finalEvent}));
    }
}

HTML Parent

<!-- Parent Component -->
<template>
    <lightning-card title="Testing Confirmation Dialog" icon-name="custom:custom60">
        <lightning-button label="Open Confirmation" slot="actions" onclick={handleClick} name="openConfirmation"></lightning-button>
        <div class="slds-text-body_regular slds-p-around--small">{displayMessage}</div>
    </lightning-card>
    <c-confirmation-dialog title='Confirmation Title'
                           message='Do you want to proceed?'
                           confirm-label='Yes'
                           cancel-label='No'
                           visible={isDialogVisible}
                           original-message={originalMessage}
                           name="confirmModal"
                           onclick={handleClick}>
    </c-confirmation-dialog>
</template>

JS - Parent Component

import {LightningElement, track} from 'lwc';

export default class ParentComponent extends LightningElement {
    @track isDialogVisible = false;
    @track originalMessage;
    @track displayMessage = 'Click on the \'Open Confirmation\' button to test the dialog.';

    handleClick(event){
        if(event.target.name === 'openConfirmation'){
            //it can be set dynamically based on your logic
            this.originalMessage = 'test message';
            //shows the component
            this.isDialogVisible = true;
        }else if(event.target.name === 'confirmModal'){

            //when user clicks outside of the dialog area, the event is dispatched with detail value  as 1
            if(event.detail !== 1){
                //gets the detail message published by the child component
                this.displayMessage = 'Status: ' + event.detail.status + '. Event detail: ' + JSON.stringify(event.detail.originalMessage) + '.';

                //you can do some custom logic here based on your scenario
                if(event.detail.status === 'confirm') {
                    //do something
                }else if(event.detail.status === 'cancel'){
                    //do something else
                }
            }

            //hides the component
            this.isDialogVisible = false;
        }
    }
}

Any help would be greatly appreciated. Thanks!

4
  • I should mention, it is also occuring just by clicking on the modal.
    – thinker
    Jul 6 '20 at 21:02
  • 1
    You need to provide the template and LWC code if you want an answer. I suspect you have something in your template related to how the events are being consumed (or not) that is causing this.
    – Phil W
    Jul 6 '20 at 21:04
  • @PhilW will get that for you. Thought it would be a quick thing I was missing.
    – thinker
    Jul 6 '20 at 21:52
  • @PhilW I have added the updated code.
    – thinker
    Jul 6 '20 at 22:40
2

The problem with your code you have defined a custom event with name click in your child component. Basically you should not use it for your custom event. It is overriding the standard onclick behavior.

//dispatch a 'click' event so the parent component can handle it
this.dispatchEvent(new CustomEvent('click', {detail: finalEvent}));

Just change the custom event name to something else:-

//dispatch a 'click' event so the parent component can handle it
 this.dispatchEvent(new CustomEvent('closemodalclick', {detail: finalEvent}));

and handle it in parent as:-

<c-child title='Confirmation Title'
                           message='Do you want to proceed?'
                           confirm-label='Yes'
                           cancel-label='No'
                           visible={isDialogVisible}
                           original-message={originalMessage}
                           name="confirmModal"
                           onclosemodalclick={handleClick}>

check the working code your here:- Playground

1
  • That was correct. Didn't realize I could just create my own name, that that it had to be a default name click, submit etc. Additionally, this onclick was bubbling all the way up the dom because i had an onlick function in that component as well. Thanks for the help, saved my butt!
    – thinker
    Jul 7 '20 at 12:27

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.