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;
}
}
}
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. |
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_ujs
… https://github.com/stimulusjs/stimulus/issues/78
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
}
}
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>