开发者

Rails custom Twitter Bootstrap modal for delete method, Problem with callback

开发者 https://www.devze.com 2023-04-08 12:52 出处:网络
Following code does destroy records as intended, but the callback is inherited from one modal to the next one. So while a record is properly deleted, Rails keeps looking to delete the formerly deleted

Following code does destroy records as intended, but the callback is inherited from one modal to the next one. So while a record is properly deleted, Rails keeps looking to delete the formerly deleted ones as well. I'm using 开发者_开发问答a Twitter Bootstrap modal window, that sits in a Rails view template and is shown when a standard Rails delete method is fired, replacing the regular javascript dialog.

How to clear the callback after it has been fired?

$.rails.allowAction = function(element) {

  var message = element.data('confirm'),
  answer = false, callback;
  if (!message) { return true; }

  if ($.rails.fire(element, 'confirm')) {
    myCustomConfirmBox(message, function() {
     callback = $.rails.fire(element,
       'confirm:complete', [answer]);
     if(callback) {
       var oldAllowAction = $.rails.allowAction;
       $.rails.allowAction = function() { return true; };
       element.trigger('click');
       $.rails.allowAction = oldAllowAction;
     }
    });
  }
  return false;
}

function myCustomConfirmBox(message, callback) {
    $('#dialog-confirm').modal('show');
    $('#dialog-confirm button.primary').click(function(){
        callback();
        $('#dialog-confirm').modal('hide');
    });
}

edit: Since I'm using the same base modal over and over again for any delete action, the callbacks queue up. So when a delete action has been cancelled before, it will still be triggered on another delete instance of a different object, since the callback is still valid. Bottom line: How to clear the callback queue?


Turns out it is a bad idea to fiddle with the native delete method/callback for various reasons. My workaround solution is as follows.

Have a "delete" button in your view, with some JS data values:

#delete button in view template
link_to "delete", "#", 
   :class => "delete_post", 
   "data-id" => YOUR_POST_ID, 
   "data-controls-modal" => "YOUR_MODAL_LAYER",
       #more bootstrap options here…

Bootstrap opens the modal window. Inside that, have another "delete" button with "remote" set, so the action will use JS.

#delete button in modal window
link_to "delete", post_path(0), 
   :method => :delete, 
   :class => "btn primary closeModal", 
   :remote => true  

CloseModal is another :class for me to know when to close the bootstrap modal window. I've put an additional function for that in my application.js. Note, the default path has a nil value, we'll attach the real post ID to be deleted via JS in the next step via the "data-id" param:

#application.js 
$('a.delete_post').live('click', function(){
    _target = $(this).data('id');
    $('#YOUR_MODAL_LAYER .primary').attr('href', '/posts/' + _target);
});

The destroy action in our Posts controller will use JS to render an animation for the deleted post:

#posts_controller.rb
def destroy
    @post = Post.find(params[:id])
    @post.destroy
    respond_to do |format|
       # format.html { redirect_to(posts_url) }
       format.js { render :content_type => 'text/javascript' }
    end
end

Insert here effects as you please. In this example we are simply fading out the deleted post:

#views/posts/destroy.js    
$("div#post-<%= params[:id] %>").fadeOut();

Altogether this works really smoothly!

0

精彩评论

暂无评论...
验证码 换一张
取 消