Reputation: 2666
Prior to Rails 5.1 I was able to use the following to customize the confirmation dialog using bootstrap styling:
$ ->
$.rails.allowAction = (link) ->
return true unless link.attr('data-confirm')
$.rails.showConfirmDialog(link)
false
$.rails.confirmed = (link) ->
link.removeAttr('data-confirm')
link.trigger('click.rails')
$.rails.showConfirmDialog = (link) ->
message = link.attr 'data-confirm'
html = """
<div class="modal" id='confirmationDialog'>
<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>#{link.data('body')}</p>
</div>
<div class='modal-footer'>
<a data-dismiss='modal' class='btn btn-default'>#{link.data('cancel')}</a>
<a data-dismiss='modal' class='btn btn-danger confirm'>#{link.data('ok')}</a>
</div>
</div>
</div>
</div>
"""
$(html).modal()
$('#confirmationDialog .confirm').on 'click', -> $.rails.confirmed(link)
The code stopped working with the change to rails_ujs? I've seen some articles on customizing it for SweetAlert2 but not bootstrap or other custom options.
Thanks.
Upvotes: 1
Views: 2879
Reputation: 91
Following Brett Green's answer, I tweaked it using Sweet Alert:
custom_confirm_dialog.js
import Rails from '@rails/ujs';
import Swal from 'sweetalert2';
Rails.confirm = (message, element) => {
console.log('message:', message)
Swal.fire({
titleText: '...',
text: '...,
showCancelButton: true,
cancelButtonText: '...',
confirmButtonText: '...',
icon: 'warning'
}).then(result => {
if(result.isConfirmed) {
const old = Rails.confirm;
Rails.confirm = () => true;
element.click();
Rails.confirm = old;
}
}).catch(error => {
console.log(error);
});
return false;
}
application.js
...
import Rails from '@rails/ujs';
Rails.start();
...
import '../src/javascripts/custom_confirm_dialog';
Working fine :)
Upvotes: 0
Reputation: 3755
For Rails 6, here's an example using bootstrap 4 dialogs:
Add modal dialog HTML to your base layout:
<div class="modal fade" id="confirmation-modal" tabindex="-1" role="dialog">
<div class="modal-dialog modal-dialog-centered modal-sm" role="document">
<div class="modal-content">
<div class="modal-body">
<span id="modal-content"></span>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-sm btn-secondary" data-dismiss="modal"><i class="fa fa-times-circle"></i> Cancel</button>
<button type="button" class="btn btn-sm btn-primary" id='ok-button'><i class="fa fa-check"></i> Continue</button>
</div>
</div>
</div>
</div>
Add javascript to override Rails.confirm and add to your global webpack:
import Rails from "@rails/ujs";
// Overrides default rails confirmation with bootstrap 4 confirm dialog
Rails.confirm = function(message, element) {
let $element = $(element)
let $dialog = $('#confirmation-modal')
let $content = $dialog.find('#modal-content')
let $ok = $dialog.find('#ok-button')
$content.text(message)
$ok.click(function(event) {
event.preventDefault()
$dialog.modal("hide")
let old = Rails.confirm
Rails.confirm = function() { return true }
$element.get(0).click()
Rails.confirm = old
})
$dialog.modal("show")
return false;
}
'#modal-content' span is replaced with message text when the link/button requiring confirmation is clicked, and then the dialog is shown.
$element is the original element which gets 'clicked' if the user clicks the OK button within the dialog. This means that however complicated your rails link/button is (using posts/gets/params, etc), this simply lets that work by physically clicking it.
Upvotes: 3
Reputation: 199
Note that in Rails 6 the confirm method of Rails UJS has been made public so that you can override it, as explained in this PR: https://github.com/rails/rails/pull/32404
Upvotes: 2
Reputation: 13
Got following working in Rails 5.2. First using console verify presence of 'Rails' and 'BootstrapDialog' object, then put the following in a file similar to ~/app/javascripts/prj.js:
"use strict"
$(document).ready(function(){
var handleConfirm = function(element) {
if (!allowAction(this)) {
Rails.stopEverything(element)
}
}
var allowAction = function(element) {
if (element.getAttribute('data-confirm') === null) {
return true
}
showConfirmDialog(element);
return false
}
var confirmed = function(element, result) {
if (result.value) {
// User clicked confirm button
element.removeAttribute('data-confirm')
element.click()
}
}
var showConfirmDialog = function(link) {
BootstrapDialog.show({
type: BootstrapDialog.TYPE_DANGER,
title: 'Are you sure?',
closable: false,
message: $(link).attr('data-confirm'),
buttons: [
{
label: 'Cancel',
action: function(dialogRef){
dialogRef.close();
}
},
{
label: 'Yes',
cssClass: 'btn-danger',
action: function(dialogRef) {
confirmed(link);
}
}
]
});
$("a[data-confirm]").on('click',handleConfirm);
});
Upvotes: 0