javascriptruby-on-railsujs

Rails 5.1: How to override allowAction in rails-ujs to use a custom confirmation dialog


In versions of Rails previous to 5.1, which used jquery_ujs, we could replace the browser's confirmation popup with our own by overriding $.rails.allowAction, as explained here.

As of Rails 5.1+, which uses rails-ujs, $.rails.allowAction is no longer available. How can we override Rails' default confirmation with our own in Rails 5 without having to switch back to jquery_ujs?

Thanks in advance.


Solution

  • I had the same challenge and I looked a little bit more into it. What I found out along the way can be read here: https://medium.com/store2be-tech/how-to-use-sweetalert2-for-your-rails-5-1-rails-ujs-confirms-without-jquery-8a5b516b2a1

    Here the final solution:

    (function() {
      var handleConfirm = function(element) {
        if (!allowAction(this)) {
          Rails.stopEverything(element)
        }
      }
    
      var allowAction = function(element) {
        if (element.getAttribute('data-confirm-swal') === null) {
          return true
        }
    
        showConfirmationDialog(element)
        return false
      }
    
      // Display the confirmation dialog
      var showConfirmationDialog = function(element) {
        var message = element.getAttribute('data-confirm-swal')
        var text = element.getAttribute('data-text')
    
        swal({
          title: message || 'Are you sure?',
          text: text || '',
          type: 'warning',
          showCancelButton: true,
          confirmButtonText: 'Yes',
          cancelButtonText: 'Cancel',
        }).then(function(result) {
          confirmed(element, result)
        })
      }
    
      var confirmed = function(element, result) {
        if (result.value) {
          // User clicked confirm button
          element.removeAttribute('data-confirm-swal')
          element.click()
        }
      }
    
      // Hook the event before the other rails events so it works togeter
      // with `method: :delete`.
      // See https://github.com/rails/rails/blob/master/actionview/app/assets/javascripts/rails-ujs/start.coffee#L69
      document.addEventListener('rails:attachBindings', function(e) {
        Rails.delegate(document, 'a[data-confirm-swal]', 'click', handleConfirm)
      })
    
    }).call(this)