primevue icon indicating copy to clipboard operation
primevue copied to clipboard

ConfirmPopup: misplaced / missing popup on stopped click event

Open multun opened this issue 1 year ago • 4 comments

Describe the bug

If the event which caused the popup to appear is stopped from propagating up to the root window, the popup is misplaced, or does not even appear, depending on whether the popup is already displayed when the event occurs.

When clicking Save, no popup appears: 2024-06-20_11-06-1718875200

When clicking Delete then Save, the popup is misplaced, as the arrow still points to Delete: 2024-06-20_11-06-1718875211

the Popover component does not exhibit the same issue.

Reproducer

stackblitz is down at the time of writting this issue

PrimeVue version

4.0.0-rc.2

Vue version

3.x

Language

TypeScript

Build / Runtime

Nuxt

Browser(s)

No response

Steps to reproduce the behavior

This can be reproduced by applying this patch to the documentation example, going to http://localhost:3000/confirmpopup/#basic, then clicking Save:

diff --git a/apps/showcase/doc/confirmpopup/BasicDoc.vue b/apps/showcase/doc/confirmpopup/BasicDoc.vue
index 241061c89..bf8725176 100644
--- a/apps/showcase/doc/confirmpopup/BasicDoc.vue
+++ b/apps/showcase/doc/confirmpopup/BasicDoc.vue
@@ -4,7 +4,7 @@
     </DocSectionText>
     <ConfirmPopup></ConfirmPopup>
     <div class="card flex flex-wrap gap-2 justify-center">
-        <Button @click="confirm1($event)" label="Save" outlined></Button>
+        <Button @click.stop="confirm1($event)" label="Save" outlined></Button>
         <Button @click="confirm2($event)" label="Delete" severity="danger" outlined></Button>
     </div>
     <DocSectionCode :code="code" />

Expected behavior

The ConfirmPopup should always show up, and be correctly placed.

multun avatar Jun 20 '24 09:06 multun

On safari the popup is misplaced more often even without the stop but I noticed that a second click on the button that would call confirm.require would make the popup move from the top left to the correct position so I dove into the code.

It looks like the alignOverlay method is only called in the outside click handler: https://github.com/primefaces/primevue/blob/8d8ca02bd375b565d99e02cb92831da6699c22d0/components/lib/confirmpopup/ConfirmPopup.vue#L199-L209

The only reason the popup would show up in the correct place is if the target is set and after that the outside click listener is triggered. Thus when we stop the propagation the outside click listener is not triggered and the popup is never aligned.

So I adding a call to alignOverlay when making the popup visible should solve this issue

Kavantix avatar Aug 11 '24 07:08 Kavantix

+1, currently blocking by this when stopping propagation for a "remove" icon that is the children of another element that have a click handler.

NamesMT avatar Sep 19 '24 04:09 NamesMT

The issue also arises when row click is enabled in the datatable and a button is placed inside one of the columns (which is another problem). In this scenario, you need to apply stopPropagation on the button to prevent the row click event from triggering, but this can cause the confirmation pop-up to appear in an incorrect location.

bobbykiselkov avatar Sep 25 '24 09:09 bobbykiselkov

On safari the popup is misplaced more often even without the stop but I noticed that a second click on the button that would call confirm.require would make the popup move from the top left to the correct position so I dove into the code.

It looks like the alignOverlay method is only called in the outside click handler:

https://github.com/primefaces/primevue/blob/8d8ca02bd375b565d99e02cb92831da6699c22d0/components/lib/confirmpopup/ConfirmPopup.vue#L199-L209

The only reason the popup would show up in the correct place is if the target is set and after that the outside click listener is triggered. Thus when we stop the propagation the outside click listener is not triggered and the popup is never aligned.

So I adding a call to alignOverlay when making the popup visible should solve this issue

Thank you! The workaround that seems to work for me is applying focus to the current element just before triggering the confirmation popup. 'event.currentTarget' seems to be undefined on click so i'm using the 'event.target' one:

const confirm = (event) => {
      event.target.focus(); // focus the clicked element so the alignOverlay function triggers
      confirm.require({
        target: event.currentTarget, //does this even do anything??
        message: 'Are you sure?,
        icon: 'pi pi-info-circle',
        rejectProps: {
          label: 'No!',
          severity: 'secondary',
          outlined: true
        },
        acceptProps: {
          label: 'Yes',
          severity: 'danger'
        },

        accept: () => {
// submitting by pressing the 'enter' key doesn't always close the confirm box, so the close method makes sure it closes properly
          confirm.close();
        }
      });
    };

WouS95 avatar Oct 09 '24 16:10 WouS95

for some reason target.focus() didn't help

but this ugly nextTick does the job

image

jcrka avatar Nov 17 '24 16:11 jcrka

Please try to use the latest version. It seems the problem was solved.

Thank you!

tugcekucukoglu avatar Nov 22 '24 07:11 tugcekucukoglu

For the ones still having this issue (while using V3) for me this worked:

nextTick(() => target.click());
confirm.require({ target, .... })

belxiors avatar Apr 30 '25 13:04 belxiors

For the ones still having this issue (while using V3) for me this worked:

nextTick(() => target.click()); confirm.require({ target, .... })

Just saved me hours of pain, thanks man

ogunsakin01 avatar Aug 13 '25 13:08 ogunsakin01