How to use SweetAlert2 for your Rails +5.1 (rails-ujs) confirms without jQuery
TL;DR see this demo project for the final solution.
Please be aware that the examples here are provided with ES6 syntax. There are different ways to get ES6 to work in Rails. The demo project has an ES5 branch for reference.
If you are reading this I assume you are familiar with Ruby on Rails and SweetAlert2. With Rails before version 5.1, when rails-ujs was still jquery-ujs, there was an easy way to hook up SweetAlert (or SweetAlert2) with the Rails confirm functionality.
One way to achieve it was to overwrite the confirm handler of Rails:
We had this solution in one of our apps and I wanted to use the new
rails-ujs. My first thought was, that it should be an easy task to adapt. Just change
Rails. and we’re good:
As it turns out some things have changed.
Rails.handleConfirm can be overwritten, but that will not override the event listener that is already attached since
rails-ujs was initialised. But no problem, let’s just write our own event handler and plug it into the new
rails-ujs way of doing things. If you have a look at the source code of the start part of rails-ujs you see how event listeners are created. The code to add an event listener for our own method then looks like this:
Alright, cool. It works for links with the attribute
data-confirm-swal="Are you sure?" now 🎉 … but wait, if you have a delete link, the confirm dialog never shows up because the method never gets called. 🤔 Turns out the event listener for
method: :delete is called earlier because it got initialised before our event listener for SweetAlert2. This is because the event listeners of
rails-ujs are hooked up directly when evaluating the code.
rails-ujs, then we get into the Problem that
Rails.delegate is not defined yet. When you require
rails-ujs this is what’s happening:
- Define event handlers and
- Attach event handlers (
So in order to get in between the definition of
Rails.delegate and the execution of
Rails.start we have to attach to the
rails:attachBindings event. (For that to happen we need to require our script before
🎉 Now everything works as expected 🎉
For the final solution have a look at this demo project (with ES5 and ES6 version) or see the code below (only ES6).
To find this all out it took me some hours as I wasn’t familiar with the codebase of
rails-ujs. But I learnt a lot along the way. Hopefully with this writeup I can help some other developers as well who want to use the latest version of Rails with SweetAlert2 and without jQuery.
If you use Webpacker, there is an easy way to get in between the
rails-ujs code and the start script: