Skip to main content

Community

Subscribe to GoRails to join the conversation. Ask questions about your code, get help adding a new feature, and discuss implementation details with other members.

How to use Sweet Alert to replace standard confirm dialog

General • Asked by Daniel Weaver


Gravatar

Daniel Weaver commented on :

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?)


Gravatar

Daniel Weaver commented on :

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.


Gravatar

Chris Oliver Mod Staff commented on :

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!


Gravatar

Daniel Weaver commented on :

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


Gravatar

Daniel Weaver commented on :

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?


Gravatar

Chris Oliver Mod Staff commented on :

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.


Gravatar

Daniel Weaver commented on :

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 :)


Gravatar

German Hernandez commented on :

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


Gravatar

Ariff Munshi commented on :

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);
  });
};

Subscribe to GoRails to join the conversation. Ask questions about your code, get help adding a new feature, and discuss implementation details with other members.