Custom dialog for data-confirm in Rails

24 篇文章 0 订阅
14 篇文章 0 订阅

Every Rails developers might be already familiar with data-confirmattribute for a link. It is used to ask for user confirmation before executing the action on behalf of user. Here is one example

 

 

<%= link_to 'Destroy', product,
  :confirm => '删除后无法恢复,你确定删除吗?',
  :method => :delete %>

 

 

The generated link looks like this:

 

<a href="/products/4" data-confirm="删除后无法恢复,你确定删除吗?"
 data-method="delete" rel="nofollow">Destroy</a>

 

 

When users click on this link, they will see a confirmation dialog to ask them if they are sure to delete that post. Some developers will wonder how it is implemented on Rails, right? Actually, there is no magic in it. If you look at application.js file in your Rails app, you will mostly see the following line

 

 

//= require jquery_ujs

 

 

 

Some developers look at it too quickly and they thought that is jQuery UI library. NO, it is not. This is jquery-ujs (https://github.com/rails/jquery-ujs) and it allows Rails to handle links with custom data- attributes such as data-method or data-confirm. More specifically, it will handle the click events on any links have these attributes and prevent the default action if necessary. You can take a look at this file if you are interested in understanding the logic behind it, https://github.com/rails/jquery-ujs/blob/master/src/rails.js

One thing I don't like about data-confirm is that it uses Javascript confirmmethod, with the default confirmation dialog of the browsers. There are many fancy and beautiful dialogs out there for us to use, and I think it would be much better if we can integrate them into our application instead of using the default one. For example, take a look at two favorite libraries which I like to use: Bootbox, SweetAlert

In order to do this, we will need to override the event handler of jquery-ujs and handle the event on our own. I created a JS script for doing this (I actually took the idea from a guy on the Internet or Stackoverflow but I forgot the link to that post). You can just copy this script and put this in your application.js.

 

//Override the default confirm dialog by rails
$.rails.allowAction = function(link){
  if (link.data("confirm") == undefined){
    return true;
  }
  $.rails.showConfirmationDialog(link);
  return false;
}
//User click confirm button
$.rails.confirmed = function(link){
  link.data("confirm", null);
  link.trigger("click.rails");
}
//Display the confirmation dialog
$.rails.showConfirmationDialog = function(link){
  var message = link.data("confirm");
  $("#dialog-confirm").dialog({
    resizable: false,
    height: "auto",
    width: 400,
    modal: true,
    buttons: {
      "确定": function() {
        $(this).dialog("close");
        $.rails.confirmed(link);
      },
      "取消": function() {
        $(this).dialog("close");
      }
    }
  });
  $("#dialog-confirm-content").html(message);
  $("#dialog-confirm").dialog("open");
}

 

Explanation

We first override allowAction method with our own method. This is the method called by jquery-ujs when user clicks on a link with data-attributes. If the link does not contain "data-confirm" attribute, we will just return and let users execute the action as normal. Otherwise, we show the confirmation dialog.

 

//Override the default confirm dialog by rails
$.rails.allowAction = function(link){
  if (link.data("confirm") == undefined){
    return true;
  }
  $.rails.showConfirmationDialog(link);
  return false;
}

 Next, we handle the case in which user clicks on the Confirm button

//User click confirm button
$.rails.confirmed = function(link){
  link.data("confirm", null);
  link.trigger("click.rails");
}

 

Notice that we set data-confirm attribute to null to avoid recursive loop and then trigger click.rails event to let the default event handler to execute the action

Finally, we handle the function to show the dialog to users.

 

//Display the confirmation dialog
$.rails.showConfirmationDialog = function(link){
  var message = link.data("confirm");
  $("#dialog-confirm").dialog({
    resizable: false,
    height: "auto",
    width: 400,
    modal: true,
    buttons: {
      "确定": function() {
        $(this).dialog("close");
        $.rails.confirmed(link);
      },
      "取消": function() {
        $(this).dialog("close");
      }
    }
  });
  $("#dialog-confirm-content").html(message);
  $("#dialog-confirm").dialog("open");
}

 

In the above script, I use JqueryUI modal-confirmation  plugin . If you want to use another library, just replace the code starting with$("#dialog-confirm")with your own modal. You would need to pay attention to the logic of handling Confirm and Cancel button to make it work properly although it is pretty straightforward.

 

/project/app/views/layouts/application.html.erb

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <title>Depot</title>
  <%= stylesheet_link_tag "application","depot","scaffold","jquery-ui-1.12.1-css/jquery-ui", :media => "all" %>
  <%= javascript_include_tag "application","jquery","jquery-ui-1.12.1-js/jquery-ui" %>
  <%= csrf_meta_tags %>
</head>
<body id="store">
  <div id="banner">
    <%= image_tag( "logo.png" ) %>
    <%= @page_title || "Pragmatic Bookshelf" %>
  </div>
  <div id="columns">
    <div id="side">
    </div>
    <div id="main">
      <%= yield %>
    </div>
  </div>
</body>
<div id="dialog-confirm" title="确认对话框" style="display:none;">
  <div id="confirm-imgs"><img src="/assets/tips.png" ></div>
  <div id="dialog-confirm-content">These items will be permanently deleted and cannot be recovered. Are you sure?</div>
</div>
</html>

 

css

 

#dialog-confirm #confirm-imgs{
    display: inline-block;
    vertical-align: middle;
}

#dialog-confirm #confirm-imgs img{
    width:60px;
    height:60px;
}

#dialog-confirm #dialog-confirm-content{
    display: inline-block;
}
#dialog-confirm-content {
    font-size:16px;
}

 



 

That's it. Let's forget boring confirm window and start using your beautiful modal.

 

http://stackoverflow.com/questions/7435859/custom-rails-confirm-box-with-rails-confirm-override

http://lesseverything.com/blog/customizing-confirmation-dialog-in-rails/#

http://stackoverflow.com/questions/4421072/jquery-ui-dialog-instead-of-alert-for-rails-3-data-confirm-attribute

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值