2

I have a delete link in Rails:

<%= link_to "#{image_tag("icons/icon_delete.png", :alt => "Delete")} Delete".html_safe, "#suppliers", id: supplier.id, class: "delete", :title => "Delete", :confirm => 'Are you sure?', :method => :delete %>

And I have a backbone event that catches it (CofeeScript):

  events: ->
    "click a.delete": "deleteSupplier"

  deleteSupplier: (event) ->
    event.preventDefault()
    console.log("delete")

All of this works fine, except that when I click OK on the confirm dialog, the link is followed. Any ideas how to prevent this? If I return false from deleteSupplier the confirmation no longer works which isn't quite what I'm after. I'd like the confirmation to work, just not follow through the link when I click OK.

EDIT: I forgot to mention that these links are inserted after the page is loaded through an ajax get request. And I also tested by removing the :confirm and it doesn't seem to make any difference. I believe it has something to do with being loaded through the ajax request, but I would have thought that the event would not even fire if that were the case :(

Ricky Nelson
  • 876
  • 10
  • 24
  • You really shouldn't be using a link for a destructive action. This has been discussed previously on SO: http://stackoverflow.com/questions/4606860/rails-3-link-to-to-destroy-not-working – Chris Salzberg Aug 15 '12 at 03:23
  • But its not just a link, it is a link with :method set to delete. jQuery then sends a delete request, not a get request, to the server which is what you don't want to do. This method is recommended rails best practice: http://guides.rubyonrails.org/form_helpers.html#how-do-forms-with-put-or-delete-methods-work – Ricky Nelson Aug 15 '12 at 03:31
  • Sorry my mistake! You're absolutely right. – Chris Salzberg Aug 15 '12 at 03:46
  • try `event.stopPropagation()`? – jakee Aug 15 '12 at 12:54

1 Answers1

5

You are playing with two forces: the Rails magic link who adds JS handlers to the link and the Backbone who also adds handlers to the link.

You better go with one and give the day free for the other. As you are using Backbone as your JS weapon let's move all the JS logic to Backbone:

<%= link_to "delete", "#suppliers", :id => supplier.id, :class => "delete", :title => "Delete" %>

deleteSupplier: function( event ) {
  event.preventDefault();
  if( confirm( "Are you sure?" ) ) {
    console.log("delete")
  }
}
fguillen
  • 36,125
  • 23
  • 149
  • 210
  • Hey fguillen I like your thinking. I had not considered putting the confirm() in my callback. This gets me a little closer I think, however I'm still having problems with the click event firing. My callback definitely gets called. If I use @jakee recommendation of stopPropogation(), the click event is definitely stopped, however it stops all events. Like the dropdown from which the link is clicked won't close. I'd like to just prevent this one thing, the click of the link from firing but so far the only way I seem to be able to stop it is to stop everything :( – Ricky Nelson Aug 18 '12 at 13:02
  • @socketwiz What about if you remove the `event.preventDefault();` and you add a `return false;` at the end of the _handler_? – fguillen Aug 18 '12 at 15:53
  • fguillen it works the same way as using stopPropogation() it seems :( – Ricky Nelson Aug 18 '12 at 17:13
  • @socketwiz You should reproduce the issue in a [jsFiddle](http://jsfiddle.net/) so we can play around. You can _fork_ my [Backbone jsFiddle playground](http://jsfiddle.net/fguillen/6frH6/), send me a _ping_ if you do it. – fguillen Aug 19 '12 at 11:13
  • OK fguillen, here you go: http://jsfiddle.net/socketwiz/6DqeR/3/ The links are pulled through an ajax request and I found a way on fiddler to put HTML through a gist, so my gist is here for reference: https://gist.github.com/3394860 – Ricky Nelson Aug 19 '12 at 14:11
  • @socketwiz I've gone to the jsfiddle but I keep having `Refused to display document because display forbidden by X-Frame-Options.` errors. In the other hand could be a clearer example if you don't use the dynamic html rendering? http://jsfiddle.net/fguillen/hkLwn/ – fguillen Aug 19 '12 at 15:34
  • You should run it in draft mode, I think fiddle is getting in the way. From the fiddle docs: http://doc.jsfiddle.net/basic/introduction.html?highlight=draft Log in to jsFiddle on your favorite browser Open or create a fiddle Hit [Run] button Open the draft page http://jsfiddle.net/draft/ on the other browser/device. It will display the last executed fiddle Reload the draft page every time you’d like to test – Ricky Nelson Aug 19 '12 at 23:25
  • @socketwiz I was able to open the _draft_ of your jsfiddle but still I don't know what you don't like from the actual behavior and what do you miss. And again I don't understand why the example has to be so complicate with the `$.post()` and the `bootstrap` effects that make the normal jsfiddle window to not work. – fguillen Aug 20 '12 at 08:45
  • "but still I don't know what you don't like from the actual behavior" Well thats simple. There are two links, when you click either one, they should not be followed because there is a preventDefault() which is supposed to prevent the default action "And again I don't understand why the example has to be so complicate with the $.post() and the bootstrap effects that make the normal jsfiddle window to not work." I wanted to make it as close to my environment as I could. Better? http://jsfiddle.net/socketwiz/6DqeR/4/ – Ricky Nelson Aug 20 '12 at 13:14
  • The first problem I have found is that there wasn't any link with class `stopclick` so of course the Backbone event handler was never triggered. I have changed the event selector by `click a.delete` and now the event is stoped: http://jsfiddle.net/fguillen/AurP5/ what next? – fguillen Aug 20 '12 at 13:27
  • fguillen, the fiddler you had me make helped me to figure it out. Your idea of choosing either rails or backbone to handle the confirmation was a good one, but there was another railsism that I overlooked, data-method="delete". Rails includes some jQuery to handle that and it was processing the event further after my callback and redirecting as it was supposed to. At any rate, now that I have removed that it works correctly. Thank you for all of your help and introducing me to this fiddler tool! – Ricky Nelson Aug 20 '12 at 13:31