【问题标题】:Rails 5.1: How to override confirmation dialog with bootstrap using rails-ujsRails 5.1:如何使用 rails-ujs 使用引导程序覆盖确认对话框
【发布时间】:2018-12-18 22:41:45
【问题描述】:

在 Rails 5.1 之前,我能够使用以下内容通过引导样式自定义确认对话框:

$ ->
  $.rails.allowAction = (link) ->
    return true unless link.attr('data-confirm')
    $.rails.showConfirmDialog(link) 
    false 

  $.rails.confirmed = (link) ->
    link.removeAttr('data-confirm')
    link.trigger('click.rails')

  $.rails.showConfirmDialog = (link) ->
    message = link.attr 'data-confirm'
    html = """
           <div class="modal" id='confirmationDialog'>
             <div class="modal-dialog">
               <div class='modal-content'>
                 <div class='modal-header'>
                   <a class='close' data-dismiss='modal'>×</a>
                   <h3>#{message}</h3>
                 </div>
                 <div class='modal-body'>
                   <p>#{link.data('body')}</p>
                 </div>
                 <div class='modal-footer'>
                   <a data-dismiss='modal' class='btn btn-default'>#{link.data('cancel')}</a>
                   <a data-dismiss='modal' class='btn btn-danger confirm'>#{link.data('ok')}</a>
                 </div>
               </div>
             </div>
           </div>
           """
    $(html).modal()
    $('#confirmationDialog .confirm').on 'click', -> $.rails.confirmed(link)

对 rails_ujs 的更改导致代码停止工作?我看过一些关于为 SweetAlert2 定制它的文章,但没有看到 bootstrap 或其他定制选项。

谢谢。

【问题讨论】:

  • jquery 不再与 rails 捆绑在一起,您是否尝试过将 jquery-ujs 包含到 Gemfile 中?
  • 听说过,没试过,但是如果有rails_ujs abd jqueryUjs,事件会被处理两次
  • 找到了可以执行此操作的 gem,gem 'data-confirm-modal'

标签: javascript ruby-on-rails coffeescript ruby-on-rails-5.1 rails-ujs


【解决方案1】:

在 Rails 5.2 中工作。首先使用控制台验证 'Rails' 和 'BootstrapDialog' 对象的存在,然后将以下内容放入类似于 ~/app/javascripts/prj.js 的文件中:

"use strict"
$(document).ready(function(){ 

  var handleConfirm = function(element) {
    if (!allowAction(this)) {
      Rails.stopEverything(element)
    }
  }

  var allowAction = function(element) {
    if (element.getAttribute('data-confirm') === null) {
      return true
    }

    showConfirmDialog(element);
    return false
  }

  var confirmed = function(element, result) {
    if (result.value) {
      // User clicked confirm button
      element.removeAttribute('data-confirm')
      element.click()
    }
  }

  var showConfirmDialog = function(link) {
    BootstrapDialog.show({
    type: BootstrapDialog.TYPE_DANGER,
    title: 'Are you sure?',
    closable: false,
    message: $(link).attr('data-confirm'),
    buttons: [
      { 
        label: 'Cancel',
        action: function(dialogRef){
          dialogRef.close();
        }
      },
      {
        label: 'Yes',
        cssClass: 'btn-danger',
        action: function(dialogRef) {
          confirmed(link);
        }
      }
    ]
  });

  $("a[data-confirm]").on('click',handleConfirm);
});

【讨论】:

  • 无法让它工作,但可能是我的 js 技能有问题
  • @Steve 你能在控制台中验证 Rails 和 BootstrapDialog 对象的存在吗?如果是,您是否也可以从控制台调用 BootstrapDialog.show() 方法来显示对话框?
【解决方案2】:

请注意,在 Rails 6 中,Rails UJS 的确认方法已公开,以便您可以覆盖它,如本 PR 中所述:https://github.com/rails/rails/pull/32404

【讨论】:

    【解决方案3】:

    对于 Rails 6,下面是一个使用 bootstrap 4 对话框的示例:

    将模态对话框 HTML 添加到您的基本布局中:

    <div class="modal fade" id="confirmation-modal" tabindex="-1" role="dialog">
      <div class="modal-dialog modal-dialog-centered modal-sm" role="document">
        <div class="modal-content">
          <div class="modal-body">
            <span id="modal-content"></span>
          </div>
          <div class="modal-footer">
            <button type="button" class="btn btn-sm btn-secondary" data-dismiss="modal"><i class="fa fa-times-circle"></i> Cancel</button>
            <button type="button" class="btn btn-sm btn-primary" id='ok-button'><i class="fa fa-check"></i> Continue</button>
          </div>
        </div>
      </div>
    </div>
    

    添加 javascript 以覆盖 Rails.confirm 并添加到您的全局 webpack:

    import Rails from "@rails/ujs";
    
    // Overrides default rails confirmation with bootstrap 4 confirm dialog
    Rails.confirm = function(message, element) {
      let $element = $(element)
      let $dialog = $('#confirmation-modal')
      let $content = $dialog.find('#modal-content')
      let $ok = $dialog.find('#ok-button')
      $content.text(message)
      $ok.click(function(event) {
          event.preventDefault()
          $dialog.modal("hide")
          let old = Rails.confirm
          Rails.confirm = function() { return true }
          $element.get(0).click()
          Rails.confirm = old
        })
      $dialog.modal("show")
      return false;
    }
    

    当点击需要确认的链接/按钮时,'#modal-content' span 被替换为消息文本,然后显示对话框。

    $element 是原始元素,如果用户单击对话框中的“确定”按钮,则该元素会被“点击”。这意味着无论您的 Rails 链接/按钮多么复杂(使用帖子/获取/参数等),这都可以通过物理单击来实现。

    【讨论】:

      【解决方案4】:

      根据Brett Green 的回答,我使用 Sweet Alert 对其进行了调整:

      custom_confirm_dialog.js

      import Rails from '@rails/ujs';
      import Swal from 'sweetalert2';
      
      Rails.confirm = (message, element) => {
        console.log('message:', message)
        Swal.fire({
          titleText: '...',
          text: '...,
          showCancelButton: true,
          cancelButtonText: '...',
          confirmButtonText: '...',
          icon: 'warning'
        }).then(result => {
          if(result.isConfirmed) {
            const old = Rails.confirm;
            Rails.confirm = () => true;
            element.click();
            Rails.confirm = old;
          }
        }).catch(error => {
          console.log(error);
        });
      
        return false;
      }
      
      

      application.js

      ...
      import Rails from '@rails/ujs';
      Rails.start();
      ...
      import '../src/javascripts/custom_confirm_dialog';
      

      工作正常:)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-08-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-12
        • 1970-01-01
        相关资源
        最近更新 更多