Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
A nice delete confirmation modal in Rails courtesy of Bootstrap

Here's what you get.

Some CoffeeScript (verbosely commented for clarity)

# Override Rails handling of confirmation

$.rails.allowAction = (element) ->
  # The message is something like "Are you sure?"
  message = element.data('confirm')
  # If there's no message, there's no data-confirm attribute, 
  # which means there's nothing to confirm
  return true unless message
  # Clone the clicked element (probably a delete link) so we can use it in the dialog box.
  $link = element.clone()
    # We don't necessarily want the same styling as the original link/button.
    .removeAttr('class')
    # We don't want to pop up another confirmation (recursion)
    .removeAttr('data-confirm')
    # We want a button
    .addClass('btn').addClass('btn-danger')
    # We want it to sound confirmy
    .html("Yes, I'm positively certain.")
    
  # Create the modal box with the message
  modal_html = """
               <div class="modal" id="myModal">
                 <div class="modal-header">
                   <a class="close" data-dismiss="modal">×</a>
                   <h3>#{message}</h3>
                 </div>
                 <div class="modal-body">
                   <p>Be certain, sonny.</p>
                 </div>
                 <div class="modal-footer">
                   <a data-dismiss="modal" class="btn">Cancel</a>
                 </div>
               </div>
               """
  $modal_html = $(modal_html)
  # Add the new button to the modal box
  $modal_html.find('.modal-footer').append($link)
  # Pop it up
  $modal_html.modal()
  # Prevent the original link from working
  return false

A well-crafted link:

<%= link_to content_tag('i', '', class: 'icon-trash'), @something, confirm: "Are you sure you want to delete '#{@something.title}'?", method: :delete %>
@trey

This comment has been minimized.

Show comment Hide comment
@trey

trey Feb 19, 2012

This is some fancy stuff. I'm gonna have to dig into this.

trey commented Feb 19, 2012

This is some fancy stuff. I'm gonna have to dig into this.

@trey

This comment has been minimized.

Show comment Hide comment
@trey

trey Feb 20, 2012

Put me to sleep with your kind boots, mister fancy man.

trey commented Feb 20, 2012

Put me to sleep with your kind boots, mister fancy man.

@keilmillerjr

This comment has been minimized.

Show comment Hide comment
@keilmillerjr

keilmillerjr Apr 12, 2012

Thank you very much! This works flawlessly.

Bootstrap places the modal near the top of the page on everything but the desktop view. Now I search to sort that out...

Thank you very much! This works flawlessly.

Bootstrap places the modal near the top of the page on everything but the desktop view. Now I search to sort that out...

@kvet

This comment has been minimized.

Show comment Hide comment
@kvet

kvet Jun 29, 2012

Very helpful! Thanks a lot!

kvet commented Jun 29, 2012

Very helpful! Thanks a lot!

@chamnap

This comment has been minimized.

Show comment Hide comment
@chamnap

chamnap Sep 15, 2012

Everything works fine except :remote => true. Any idea?

chamnap commented Sep 15, 2012

Everything works fine except :remote => true. Any idea?

@coty

This comment has been minimized.

Show comment Hide comment
@coty

coty Oct 25, 2012

Just wanted to say, "Thanks." Worked like a charm, and I learned a bit at the same time.

coty commented Oct 25, 2012

Just wanted to say, "Thanks." Worked like a charm, and I learned a bit at the same time.

@kandadaboggu

This comment has been minimized.

Show comment Hide comment
@kandadaboggu

kandadaboggu Dec 28, 2012

The modal dialogue doesn't disappear while using remote link(i.e. remote: true) .

The modal dialogue doesn't disappear while using remote link(i.e. remote: true) .

@kandadaboggu

This comment has been minimized.

Show comment Hide comment
@kandadaboggu

kandadaboggu Dec 28, 2012

I had to add the following code after .removeAttr('data-confirm') line to get this to work with remote links.

# data-dismiss property is required for remote links
.attr('data-dismiss', 'modal')

I had to add the following code after .removeAttr('data-confirm') line to get this to work with remote links.

# data-dismiss property is required for remote links
.attr('data-dismiss', 'modal')
@chrisstr

This comment has been minimized.

Show comment Hide comment
@chrisstr

chrisstr Jan 3, 2013

It fails for me when calling $modal_html.modal(). After some googling, I found the jQuery-Plugin Simplemodal (http://www.ericmmartin.com/projects/simplemodal/) which provides that function.
It works now using this plugin - am I missing something or is it obvious for everyone else here that this is needed?

chrisstr commented Jan 3, 2013

It fails for me when calling $modal_html.modal(). After some googling, I found the jQuery-Plugin Simplemodal (http://www.ericmmartin.com/projects/simplemodal/) which provides that function.
It works now using this plugin - am I missing something or is it obvious for everyone else here that this is needed?

@SirNerdBear

This comment has been minimized.

Show comment Hide comment
@SirNerdBear

SirNerdBear Jan 13, 2013

@chrisstr modal is part of Twitter bootstrap. If you've not already checked it out I highly recommend it.

Thanks for this awesome postpostmodern!

@chrisstr modal is part of Twitter bootstrap. If you've not already checked it out I highly recommend it.

Thanks for this awesome postpostmodern!

@luizvarela

This comment has been minimized.

Show comment Hide comment
@luizvarela

luizvarela Jan 24, 2013

Thanks, this is awesome!!! o/

Thanks, this is awesome!!! o/

@findchris

This comment has been minimized.

Show comment Hide comment
@findchris

findchris Jan 26, 2013

Is it just me or does the confirm button not work subsequent to clicking the cancel button the first time?

Is it just me or does the confirm button not work subsequent to clicking the cancel button the first time?

@victorngkp

This comment has been minimized.

Show comment Hide comment
@victorngkp

victorngkp Mar 26, 2013

Is there anyway we can submit the form, in this case the "Delete" button just by hitting the "Enter" key?

Is there anyway we can submit the form, in this case the "Delete" button just by hitting the "Enter" key?

@vjt

This comment has been minimized.

Show comment Hide comment
@vjt

vjt Jul 2, 2013

Hey,

Also check out this gem that politely hooks into the Rails' UJS adapter (via the confirm event) without overriding its allowAction completely. :-)

vjt commented Jul 2, 2013

Hey,

Also check out this gem that politely hooks into the Rails' UJS adapter (via the confirm event) without overriding its allowAction completely. :-)

@chevinbrown

This comment has been minimized.

Show comment Hide comment
@chevinbrown

chevinbrown Jul 10, 2013

Well done! I'm always thrilled to see drop-in solutions for rails. :)

Well done! I'm always thrilled to see drop-in solutions for rails. :)

@kacole2

This comment has been minimized.

Show comment Hide comment
@kacole2

kacole2 Nov 7, 2013

this is fantastic! here is the updated modal to work with bootstrap 3.

# Create the modal box with the message
  modal_html = """
               <div id="myModal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
                <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>Are you sure you want to do this?</p>
                   <p>There's no turning back.</p>
                 </div>
                 <div class="modal-footer">
                   <button class="btn" data-dismiss="modal" aria-hidden="true">Cancel</button>
                 </div>
               </div>
              </div>
             </div>  
               """

kacole2 commented Nov 7, 2013

this is fantastic! here is the updated modal to work with bootstrap 3.

# Create the modal box with the message
  modal_html = """
               <div id="myModal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
                <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>Are you sure you want to do this?</p>
                   <p>There's no turning back.</p>
                 </div>
                 <div class="modal-footer">
                   <button class="btn" data-dismiss="modal" aria-hidden="true">Cancel</button>
                 </div>
               </div>
              </div>
             </div>  
               """
@rnaud

This comment has been minimized.

Show comment Hide comment
@rnaud

rnaud Feb 12, 2014

If anyone else has this problem, be careful about confirm on forms. This works great for links, but it doesn't work in you put the confirm on the submit button of your form.

rnaud commented Feb 12, 2014

If anyone else has this problem, be careful about confirm on forms. This works great for links, but it doesn't work in you put the confirm on the submit button of your form.

@webkhung

This comment has been minimized.

Show comment Hide comment
@webkhung

webkhung Mar 4, 2014

I just noticed the same thing about putting the confirmation on a submit button of a form. It doesn't work.

webkhung commented Mar 4, 2014

I just noticed the same thing about putting the confirmation on a submit button of a form. It doesn't work.

@hecbuma

This comment has been minimized.

Show comment Hide comment
@hecbuma

hecbuma Jul 31, 2015

Hi @maud, @webkhung I made this work by adding a dirty condition

  if element.get(0).tagName == "BUTTON"
    random_id = Math.random().toString(36).substring(7)
    $form = element.parent('form')
    $form.attr('id', random_id)
    $link.attr('onClick', "document.getElementById('#{random_id}').submit();")

This is the full snippet

.rails.allowAction = (element) ->
  # The message is something like "Are you sure?"
  message = element.data('confirm')
  # If there's no message, there's no data-confirm attribute,
  # which means there's nothing to confirm
  return true unless message
  # Clone the clicked element (probably a delete link) so we can use it in the dialog box.
  $link = element.clone()
  # We don't necessarily want the same styling as the original link/button.
  .removeAttr('class')
  # We don't want to pop up another confirmation (recursion)
  .removeAttr('data-confirm')
  #  We want a button
  .addClass('btn').addClass('btn-danger')
  # We want it to sound confirmy
  .html("Yes, I'm positively certain.")

  if element.get(0).tagName == "BUTTON"
    random_id = Math.random().toString(36).substring(7)
    $form = element.parent('form')
    $form.attr('id', random_id)
    $link.attr('onClick', "document.getElementById('#{random_id}').submit();")

  # Create the modal box with the message
  modal_html = """
               <div id="myModal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
                <div class="modal-dialog">
                  <div class="modal-content">
                    <div class="modal-header">
                   <p>#{message}</p>
                 </div>
                 <div class="modal-body">
                   <p>Are you sure?</p>
                 </div>
                 <div class="modal-footer">
                   <button class="btn" data-dismiss="modal" aria-hidden="true">Cancel</button>
                 </div>
               </div>
              </div>
             </div>
               """
  $modal_html = $(modal_html)
  # Add the new button to the modal box
  $modal_html.find('.modal-footer').append($link)
  # Pop it up
  $modal_html.modal()
  # Prevent the original link from working
  return false

hecbuma commented Jul 31, 2015

Hi @maud, @webkhung I made this work by adding a dirty condition

  if element.get(0).tagName == "BUTTON"
    random_id = Math.random().toString(36).substring(7)
    $form = element.parent('form')
    $form.attr('id', random_id)
    $link.attr('onClick', "document.getElementById('#{random_id}').submit();")

This is the full snippet

.rails.allowAction = (element) ->
  # The message is something like "Are you sure?"
  message = element.data('confirm')
  # If there's no message, there's no data-confirm attribute,
  # which means there's nothing to confirm
  return true unless message
  # Clone the clicked element (probably a delete link) so we can use it in the dialog box.
  $link = element.clone()
  # We don't necessarily want the same styling as the original link/button.
  .removeAttr('class')
  # We don't want to pop up another confirmation (recursion)
  .removeAttr('data-confirm')
  #  We want a button
  .addClass('btn').addClass('btn-danger')
  # We want it to sound confirmy
  .html("Yes, I'm positively certain.")

  if element.get(0).tagName == "BUTTON"
    random_id = Math.random().toString(36).substring(7)
    $form = element.parent('form')
    $form.attr('id', random_id)
    $link.attr('onClick', "document.getElementById('#{random_id}').submit();")

  # Create the modal box with the message
  modal_html = """
               <div id="myModal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
                <div class="modal-dialog">
                  <div class="modal-content">
                    <div class="modal-header">
                   <p>#{message}</p>
                 </div>
                 <div class="modal-body">
                   <p>Are you sure?</p>
                 </div>
                 <div class="modal-footer">
                   <button class="btn" data-dismiss="modal" aria-hidden="true">Cancel</button>
                 </div>
               </div>
              </div>
             </div>
               """
  $modal_html = $(modal_html)
  # Add the new button to the modal box
  $modal_html.find('.modal-footer').append($link)
  # Pop it up
  $modal_html.modal()
  # Prevent the original link from working
  return false
@peterkle

This comment has been minimized.

Show comment Hide comment
@peterkle

peterkle Apr 21, 2016

Does anyone know how to integration test this in rspec/capybara? I'm stuck:

scenario 'user can delete post' do
   ...
    visit posts_path
    click_link 'Delete'
    #page.driver.browser.switch_to.alert.accept <-- This no longer works because we overwrote it
    ...
  end

Does anyone know how to integration test this in rspec/capybara? I'm stuck:

scenario 'user can delete post' do
   ...
    visit posts_path
    click_link 'Delete'
    #page.driver.browser.switch_to.alert.accept <-- This no longer works because we overwrote it
    ...
  end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment