В версиях Rails, предшествующих 5.1, в которых использовалось jquery_ujs, мы могли заменить всплывающее окно подтверждения браузера своим собственным путем переопределения $.rails.allowAction, как объяснено здесь.

Начиная с Rails 5.1+, где используется rails-ujs, $.rails.allowAction больше недоступен. Как мы можем переопределить подтверждение по умолчанию в Rails своим собственным в Rails 5, не переключаясь обратно на jquery_ujs?

Заранее спасибо.

3
BrunoFacca 28 Авг 2017 в 19:51

3 ответа

Лучший ответ

У меня была такая же проблема, и я немного больше в нее посмотрел. То, что я узнал по пути, можно прочитать здесь: https://medium.com/store2be-tech/how-to-use-sweetalert2-for-your-rails-5-1-rails-ujs- подтверждает - без - JQuery - 8a5b516b2a1

Вот окончательное решение:

(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)
4
peterfication 2 Дек 2017 в 15:25

Я не нашел красивый способ настройки rails_ujs, поэтому я пришел с этим обходным путем (используя CoffeeScript):

` ` `

$(document).on 'mousedown', 'a[data-confirm]', (e) ->
  e.preventDefault()
  link = $(e.target)

  message = link.data 'confirm'
  modal = $('.modal.confirmation')
  modal.find('.content').text(message)
  approve = modal.find('.approve')
  approve.attr('data-method', link.data('method'))
  approve.attr('href', link.attr('href'))

  modal.modal('show')

` ` `

Событие Mousedown позволяет моему обработчику событий выполняться первым (оно происходит до события click, которое использует rails_ujs)

2
M. Stavnycha 10 Ноя 2017 в 12:47

Вы можете переопределить его с помощью Rails.confirm, например, с CoffeeScript:

Rails.confirm = (message, element) ->
  # your code

Например чтобы текст подтверждения отображался в течение 2 секунд:

WAITING_CLASS = "waiting-for-confirmation"
TIMEOUT = 2000

Rails.confirm = (message, element) ->
  if element.classList.contains(WAITING_CLASS)
    true
  else
    element.dataset.beforeConfirm = element.textContent
    element.textContent = element.dataset.confirm
    element.classList.add(WAITING_CLASS)

    timeout TIMEOUT, ->
      element.classList.remove(WAITING_CLASS)
      element.textContent = element.dataset.beforeConfirm

    false

Смотрите: https: //github.com/rails/rails/blob/master/actionview/app/assets/javascripts/rails-ujs/features/confirm.coffee

И timeout, и просто простая функция, которая инвертирует параметры setTimeout:

var timeout = function(time, callback) {
  setTimeout(callback, time)
}
0
localhostdotdev 30 Мар 2019 в 01:14