Custom rails confirm box (with $.rails.confirm override)

前端 未结 4 1796
伪装坚强ぢ
伪装坚强ぢ 2021-02-05 15:57

I\'ve been tinkering with this for a long long time.

I would like to hijack the default JS confirm dialog with something I rolled myself. I\'d like to use a completely c

相关标签:
4条回答
  • 2021-02-05 16:28

    I wrote a sample for Rails 3.1 to change the alerts using this solution, but instead of replacing the native alert with the bootstrap one, it does the following:

    • Change the link/button text to 'Sure?' for 2 seconds
    • If the link/button is clicked within 2 seconds, the action is performed
    • Otherwise the link/button flips back to the old text and nothing happens.

    Here is a gist: https://gist.github.com/2594409

    This is following this discussion in the UX forum:

    https://ux.stackexchange.com/questions/20741/action-confirmation-through-double-clicking

    0 讨论(0)
  • 2021-02-05 16:32

    I am posting my working solution in case it helps anybody. This solution renders a Bootstrap Modal when clicking link or button matched via following selectors:

    $('a.ajaxLink, button.ajaxButton')

    HAML code

    - genericConfirmationModalId = "genericConfirmationModal"
    .modal.fade{:role => "dialog", :tabindex => "-1", id: genericConfirmationModalId }
      .modal-dialog{:role => "document"}
        .modal-content
          .modal-body
            %button.close{"aria-label" => "Close", "data-dismiss" => "modal", :type => "button"}
              %span{"aria-hidden" => "true"} ×
    
            %h3.text-center<
              Are you sure?
    
          .modal-footer
            .row<
              .col-md-6<
                = button_tag(type: 'button', class: "btn btn-primary btn-lg genericConfirmationModalNoBtn" ) { "No" }
              .col-md-6<
                = button_tag(type: 'button', class: "btn btn-danger btn-lg genericConfirmationModalYesBtn") { "Yes" }
    

    JS Code

    (function ($) {
      // ================ STARTS - CUSTOM rails_ujs CONFIRMATION DIALOG RELATED JS
    
      blockUI = function() {
        $.blockUI();
      };
    
      unblockUI = function() {
        $.unblockUI();
      };    
    
      // Reference: http://thelazylog.com/custom-dialog-for-data-confirm-in-rails/
      $.rails.confirmed = function(element) {
        hideGenericConfirmationModal();
        element.attr('data-confirmation-answer', '1');
        element.trigger('click.rails');
      }
    
      // Overridden version
      // Reference: https://github.com/rails/jquery-ujs/blob/master/src/rails.js#L88
      $.rails.allowAction = function(element) {
        var message = element.data('confirm'),
            answer = false, callback;
        if (!message) { return true; }
    
        var executeCustomBehavior = !!element.attr('data-confirmation-answer');
    
        if (executeCustomBehavior) {
          answer = element.attr('data-confirmation-answer') == '1' ? true : false;
          callback = $.rails.fire(element, 'confirm:complete', [answer]);
        } else {
          if ($.rails.fire(element, 'confirm')) {
            try {
              answer = $.rails.confirm(message);
            } catch (e) {
              (console.error || console.log).call(console, e.stack || e);
            }
            callback = $.rails.fire(element, 'confirm:complete', [answer]);
          }
        }
    
        return answer && callback;
      };
    
      bindblockUIOnAjaxLinks = function() {
        $('a.ajaxLink, button.ajaxButton').off('click').on('click', function() {
          var linkTriggersConfirmationDialog = !!$(this).attr('data-confirm');
    
          if (linkTriggersConfirmationDialog) {
            // Reference: http://stackoverflow.com/questions/19516654/rails-ujs-confirm-box-cancel-button-callback
            $(this).on('confirm:complete', function(e, response) {
              if(response) {
                blockUI(); // Block and Unblock UI was applicable in my case. It is not necessary to use this solution.
              } else {
                unblockUI();
              }
            });
    
            bindShowEventOnGenericConfirmationModal($(this));
            showGenericConfirmationModal();
            return false;
    
          } else {
            blockUI();
          }
        });
      };
    
      isGenericConfirmationModalAnswerYes = function() {
        return genericConfirmationModalAnswerHiddenField().val() == '1';
      };
    
      genericConfirmationModal = function() {
        return $("#genericConfirmationModal");
      };
    
      genericConfirmationModalYesBtn = function() {
        return genericConfirmationModal().find('.genericConfirmationModalYesBtn');
      };
    
      bindClickEventOnGenericConfirmationYesBtn = function(elementTriggeredConfirmation) {
        genericConfirmationModalYesBtn().off("click").on("click", function(event) {
          // console.log("generic confirmation modal yes button event callback");
          $.rails.confirmed(elementTriggeredConfirmation);
        });
      };
    
      genericConfirmationModalNoBtn = function() {
        return genericConfirmationModal().find('.genericConfirmationModalNoBtn');
      };
    
      bindClickEventOnGenericConfirmationNoBtn = function() {
        genericConfirmationModalNoBtn().off("click").on("click", function(event) {
          //    console.log("generic confirmation modal no button event callback");
          hideGenericConfirmationModal();
          unblockUI();
        });
      };
    
      showGenericConfirmationModal = function() {
        genericConfirmationModal().modal('show');
      };
    
      bindShowEventOnGenericConfirmationModal = function(elementTriggeredConfirmation) {
        genericConfirmationModal().off('shown.bs.modal').on('shown.bs.modal', function (event) {
          // console.log("generic confirmation modal shown event callback");
          bindHideEventOnGenericConfirmationModal();
          bindClickEventOnGenericConfirmationYesBtn(elementTriggeredConfirmation);
          bindClickEventOnGenericConfirmationNoBtn();
        })
      };
    
      hideGenericConfirmationModal = function() {
        genericConfirmationModal().modal('hide');
      };
    
      bindHideEventOnGenericConfirmationModal = function() {
        genericConfirmationModal().off('hidden.bs.modal').on('hidden.bs.modal', function (event) {
          // console.log("generic confirmation modal hidden event callback");
          // Nothing to handle as of now
        })
      };
    
      // ================ ENDS - CUSTOM rails_ujs CONFIRMATION DIALOG RELATED JS
    
    }) (jQuery);
    
    var ready;
    
    ready = function() {
      bindblockUIOnAjaxLinks();
    };
    
    // References:
    //  http://stackoverflow.com/questions/18769109/rails-4-turbo-link-prevents-jquery-scripts-from-working
    //  http://stackoverflow.com/questions/18770517/rails-4-how-to-use-document-ready-with-turbo-links
    $(document).ready(ready);
    $(document).on('page:load', ready);
    
    0 讨论(0)
  • 2021-02-05 16:34

    Here's a working demo for changing confirmation box in Rails: http://rors.org/demos/custom-confirm-in-rails

    Examples for Boostrap, jQueryUI and Noty are provided.

    0 讨论(0)
  • 2021-02-05 16:43

    there is pull request with this feature which seems to work fine https://github.com/rails/jquery-ujs/pull/196

    0 讨论(0)
提交回复
热议问题