Ask A Question

Notifications

You’re not receiving notifications from this thread.

How to use Sweet Alert to replace standard confirm dialog

Daniel Weaver asked in General

I'm trying to use Sweet Alert to replace the standard Rails confirm dialog. I can get it working in a plain new Rails app but not in my production app.

I'm using the sweet-alert-confirm gem here: https://github.com/mois3x/sweet-alert-rails-confirm

When I hit a Delete link the confirm dialog is skipped entirely and the record is immediately deleted.

<td><%= link_to 'Destroy', user, method: :delete, remote: true, data: { confirm: 'Delete this user?' } %></td>

In a plain Rails app this line works but in my prod app it doesn't. I assume there is something interfering with the JS. The console in Chrome shows nothing unusual and the Rails server log just shows the usual delete action:

Started DELETE "/users/17" for ...
Processing by UsersController#destroy as JS
  Parameters: {"id"=>"17"}
  User Load (0.4ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 2 LIMIT 1

My question is: how do I go about tracking down the conflict?

(Chris - you got the behaviour I need in your tutorial episode without using the sweet-alert-confirm gem - how did you do that?)

Reply

I should also mention that I can get a usual Sweet Alert dialog to show by using sweetAlert('Hi'); - it's just the confirm dialog I'm having difficulty with.

Reply

You'll basically need to write your own JS to handle the DELETE request (my example wasn't fully functional). Don't use the data-confirm from Rails because that will conflict.

Here's a quick and dirty example that needs some refactoring, but should do the trick for you.

First you'll want to update the delete link and give it a behavior:

<td><%= link_to 'Destroy', user, data: { behavior: 'delete' } %></td>

Then you need to write some JS to listen for clicks on this link. It will do the following things

  1. Display the dialog
  2. Submits a DELETE to the url if confirmed (cancels if not confirmed)
  3. Updates the dialog when the DELETE is successful
jQuery ->
  $("[data-behavior='delete']").on "click", (e) ->
    e.preventDefault()

    swal {
      title: 'Are you sure?'
      text: 'You will not be able to recover this imaginary file!'
      type: 'warning'
      showCancelButton: true
      confirmButtonColor: '#DD6B55'
      confirmButtonText: 'Yes, delete it!'
      cancelButtonText: 'No, cancel plx!'
      closeOnConfirm: false
      closeOnCancel: false
    }, (confirmed) =>
      if confirmed
        $.ajax(
          url: $(this).attr("href")
          dataType: "JSON"
          method: "DELETE"
          success: =>
            swal 'Deleted!', 'Your imaginary file has been deleted.', 'success'
            # TODO: Also remove the item from the page
        )

      else
        swal 'Cancelled', 'Your imaginary file is safe :)', 'error'
      return

In the success callback there, you'll want to also remove the item from the page, but I'll leave that up to you since it's application specific.

And that's it!

Reply

Thanks Chris, this looks great! I'll give it a try tomorrow.

Have you seen the sweet-alert-confirm gem? It does a similar thing, overriding the default confirm dialog, but it does it using the regular Rails method with data-confirm. Any thoughts on which way is best?

https://github.com/mois3x/sweet-alert-rails-confirm

Reply

Chris, I just added your code and it's working great. I think I understand it all - I'm still getting used to CoffeeScript syntax.

How would I pass some data from the view into the JS, like the model class, 'User', so I could show 'Delete this user?' in the dialog?

Reply

Great question! That's what data attributes are really useful for.

You can just add data attributes like data-type="user" to the a tag. Then your JS can grab it with $(this).data("type") and that will return the string "user" which you can simply plug into the string for the dialog.

Reply

Perfect, works like a charm, thanks Chris.

I'd still like to look into a solution that integrates/overrides the standard Rails data-confirm so that I can write standard code in my views then choose whether to use an override library like SweetAlert or just leave it as regular Rails alerts.

In the meantime this solution is working great :)

Reply

you just save me a ton of time, thks :D

Reply

Hey came across this thread as I was facing the same problem. I tried to stay away from them gems initially and downloaded Sweet Alerts 2 from source. All worked well until I had to the confirmation alert with a POST request callback after confirmation. As Chris mentioned, you will have to write your own Javascript and looking at the rails_ujs source, it required quite a bit of work.

Went the gem way and installed sweet-alerts and sweet-alerts-confirm. Did not work.

So here is my solution adapted from http://thelazylog.com/custom-dialog-for-data-confirm-in-rails/.

Basically overwrites the allowAction method call.

//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");
  swal({
    title: message,
    type: 'warning',
    confirmButtonText: 'Sure',
    confirmButtonColor: '#2acbb3',
    showCancelButton: true
  }).then(function(e){
    $.rails.confirmed(link);
  });
};
Reply

If you're using a Rails helper, you can do this:

<%= link_to path,
method: :delete,
data: {
confirm: "Confirmation message",
'confirm-button-text': 'Confirm',
'cancel-button-text': 'Cancel'
} do %>
Your link text with or whatever
<% end %>

Reply
Join the discussion
Create an account Log in

Want to stay up-to-date with Ruby on Rails?

Join 85,376+ developers who get early access to new tutorials, screencasts, articles, and more.

    We care about the protection of your data. Read our Privacy Policy.