Wait for alert confirmation to run Stimulus code

I wanted to run some stimulus code when I delete an element in my DOM.
But I also wanted to get a confirmation from the user, thanks to a native alert (“Are you sure you want to delete this element?”).
But It seems the Stimulus code is triggered before my alert acceptance.
Is there any way to trigger it after?
Thank you

Sounds like what you want is Window.confirm, not Window.alert.

MDN: https://developer.mozilla.org/en-US/docs/Web/API/Window/confirm

Sorry. I made a mistake in my first. It is a confirm.
But I wanted to use the confirm: option in rails link_to.
So I can’t precisely control the flow.
The confirm will have to be in the stimulus controller instead.
Thank you.

If you are using rails_ujs and remote: true for the delete links…
you can add actions for ajax:beforeSend and ajax:success.

Here is one example using a delete link with remote: true and the rails confirm helper.

View

  <tbody data-controller="projects">
    <% @projects.each do |project| %>
      <tr>
        <td><%= project.title %></td>
        <td><%= link_to 'Show', project %></td>
        <td><%= link_to 'Edit', edit_project_path(project) %></td>
        <td><%= link_to 'Destroy', 
                        project, 
                        remote: true, 
                        method: :delete, 
                        data: {
                          confirm: 'Are you sure?', 
                          action: 'ajax:beforeSend->proje
cts#onBeforeDelete ajax:success->projects#onDelete' 
                        } %></td>
      </tr>
    <% end %>
  </tbody>

projects_controller.js

iimport { Controller } from 'stimulus';

export default class extends Controller {
  connect() {
    console.log('connected');
  }
  onBeforeDelete(e) {
    console.log('do stuff before ajax call')
    this.elementToDelete = e.currentTarget.closest('tr');
    // e.preventDefault() stops ajax
  }

  onDelete(e) {
    const [data, status, xhr] = e.detail;

    if (this.elementToDelete) {
      this.elementToDelete.parentNode.remove();
      this.elementToDelete = null;
    }
  }
}
2 Likes

Oh. Awesome. Exactly what I was looking for. Is there any documentation on the Ajax event triggered by Rails UJS?

Thank you

Dimitri Bosch

Yep, it’s in the rails documentation: Working with JavaScript in Rails

Event name Extra parameters (event.detail) Fired
ajax:before Before the whole ajax business.
ajax:beforeSend [xhr, options] Before the request is sent.
ajax:send [xhr] When the request is sent.
ajax:stopped When the request is stopped.
ajax:success [response, status, xhr] After completion, if the response was a success.
ajax:error [response, status, xhr] After completion, if the response was an error.
ajax:complete [xhr, status] After the request has been completed, no matter the outcome.
2 Likes

Perfect. Thank you very much.

Just for the record and to save sometime to others…

I was having a problem making the ujs ajax events work, and I found that the problem was that I was using jquery_ujs instead of rails_ujshttps://github.com/stimulusjs/stimulus/issues/78

1 Like

I know it is an old discussion but I found myself here and an other simple solution is to call ‘confirm’ in the stimulus action method, for example :

 delete(event) {
    Rails.stopEverything(event)
    let confirmDialog = confirm("Are you sure ?")
    if (confirmDialog == true) {
      // your logic
    }
}
1 Like

I also just ran into this issue and published a quick write-up of my solution.

tl;dr

You can listen for the confirm:complete event:

<button data-reflex-dataset="combined"
        data-confirm="Are you sure you want to remove this context?"
        data-reflex="confirm:complete->Context#remove_context">
  <%= render_svg 'icons/custom/remove' %>
</button>