Javascript Rails 5.1:如何覆盖Rails ujs中的allowAction以使用自定义确认对话框

Javascript Rails 5.1:如何覆盖Rails ujs中的allowAction以使用自定义确认对话框,javascript,ruby-on-rails,ujs,Javascript,Ruby On Rails,Ujs,在5.1之前的Rails版本中,使用了jquery\u ujs,我们可以通过覆盖$.Rails.allowAction来替换浏览器的确认弹出窗口 从Rails 5.1+开始,它使用Rails ujs,$.Rails.allowAction不再可用。我们如何在Rails 5中用自己的默认确认覆盖Rails的默认确认,而不必切换回jquery\u ujs 提前感谢。我还没有找到一种很好的方法来调整rails_ujs,所以我提供了这个解决方法(使用CoffeeScript): ``` ``` Mous

在5.1之前的Rails版本中,使用了
jquery\u ujs
,我们可以通过覆盖
$.Rails.allowAction
来替换浏览器的确认弹出窗口

从Rails 5.1+开始,它使用
Rails ujs
$.Rails.allowAction
不再可用。我们如何在Rails 5中用自己的默认确认覆盖Rails的默认确认,而不必切换回
jquery\u ujs


提前感谢。

我还没有找到一种很好的方法来调整rails_ujs,所以我提供了这个解决方法(使用CoffeeScript):

```

```


Mousedown事件允许首先执行我的事件处理程序(它在rails_ujs使用的click事件之前执行)

我也遇到了同样的挑战,我对此进行了更多的研究。我一路上发现的情况可以在这里阅读:

最后的解决方案如下:

(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)

您可以使用
Rails覆盖它。确认
,例如使用CoffeeScript:

Rails.confirm=(消息,元素)->
#你的代码
e、 g.要使确认文本显示2秒钟:

WAITING\u CLASS=“等待确认”
超时=2000
Rails.confirm=(消息,元素)->
if元素.classList.contains(等待类)
真的
其他的
element.dataset.beforeConfirm=element.textContent
element.textContent=element.dataset.confirm
element.classList.add(等待类)
超时,->
element.classList.remove(等待类)
element.textContent=element.dataset.beforeConfirm
假的
见:

timeout
以及一个简单的函数,它反转
setTimeout
参数:

var timeout=函数(时间,回调){
setTimeout(回调,时间)
}

随着时间的推移,rails团队已经更改了这些方法的名称和签名,因此在开始编写覆盖之前,检查与rails版本相关的代码版本是值得的。例如。
(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)