Overriding the default confirm behaviour on phoenix.html.link

While trying to override the default confirm behaviour of phoenix.link.click in live view, the operation happens already without waiting for confirmation from the user. I’m using vex for creating custom confirm dialog like in the docs below.

https://hexdocs.pm/phoenix_html/Phoenix.HTML.Link.html#link/2-overriding-the-default-confirm-behaviour

1 Like

Me too facing the same problem, Please anyone can help us.

has anyone been able to resolve this one?

Still an issue in 2022 :frowning_face:. Following the exact instructions with vex leads to the click event happening anyway, regardless of the vex prompt.

I came across this thread while seeing the same issues (in 2024). I think it might have been caused by not loading the vex css. In case it helps anyone, this is the working setup I ended up with (this is an old project using webpack – I assume it’ll be a bit different with esbuild):

(cd assets && npm install --save vex-js vex-dialog)

New file assets/js/confirm_dialog.js (for tidyness):

import vex from "vex-js"
import vex_dialog from "vex-dialog"
vex.registerPlugin(vex_dialog)
vex.defaultOptions.className = 'vex-theme-os'

function init() {
  document.body.addEventListener('phoenix.link.click', function (e) {
    e.stopPropagation();
    var message = e.target.getAttribute("data-confirm");
    if(!message){ return true; }
    vex.dialog.confirm({
      message: message,
      callback: function (value) {
        if (value == false) { e.preventDefault(); }
      }
    })
  }, false);
}

export default { init: init }

In assets/js/app.js:

import ConfirmDialog from "./confirm_dialog"
…
 $(document).ready(function() {
   …
  ConfirmDialog.init()
  …
})

In assets/css/app.scss:

@import "../node_modules/vex-js/dist/css/vex";
@import "../node_modules/vex-js/dist/css/vex-theme-os";
1 Like

Sorry, replying to myself. I thought that worked, but all I’d managed to do was get the dialog to show up. The liveview still receives the click event immediately, and handles it while the dialog is still displayed.

I believe @Neophen posted on this yesterday: Beter data-confirm modals in Phoenix LiveView - DEV Community

I have yet to try this out though.

yeah i forgot i wanted to post this here somewhere :smiley:

@kerryb the problem with the vex solution lies in the fact that e.preventDefault needs to be instant, the event handlers are instant you can’t really await on them. Hence in my implementation i prevent it if it has a data-confirm and then re-trigger on the success case, you could adjust it based on your modal/dialog, i just used the native dialog method and created promise with closures to handle the results.

Also, my implementation just puts the markup dialog into the html markup as a live component. You could put it into a template tag and create it a dialog from there. ofcourse make sure to remove the dialog after resolving it.

1 Like

Thanks for writing this, @Neophen . Works great in my tests so far!

Do you think it could work as a dep/lib? I would be happy to assist.

Not sure it’s just two code snippets, and it really depends on the way users want to implement it.

I think what could be good is to somehow add this example to the docs, as it is just wrong in the docs.

https://hexdocs.pm/phoenix_live_view/Phoenix.Component.html#link/1-overriding-the-default-confirm-behaviour

Created a pr

It’s been merged, should be part of the docs on the new version of liveview

1 Like