Stimulus Discourse

Wait for alert confirmation to run Stimulus code


#1

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


#2

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

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


#3

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.


#4

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

#5

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

Thank you

Dimitri Bosch


#6

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.

#7

Perfect. Thank you very much.


#8

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