I am using rails form_with
as a remote form. Before submission I want to display a custom confirm box with a dynamic message. After the box is indeed confirmed I want to eventually submit the form.
I came up with 'ajax:beforeSend' event handler :
const form = document.getElementById('assign_sessions_to_employees')
form.addEventListener(
'ajax:beforeSend',
(event) => {
event.preventDefault();
swal.fire({
title: 'Are you sure ?',
text: `You are about to spend ${expectedExpenditure()} credits.`,
showCancelButton: true,
}).then((result) => {
if (result.isConfirmed) {
console.log('submitting')
Rails.fire(form, 'submit');
}
})
}
)
This works fine, however when I run Rails.fire(form, 'submit');
, when I eventually want to submit the form this retriggers 'ajax:beforeSend'
and I get stuck in the loop.
What would be the correct way to achieve this behavior with form_with and rails ujs ?
If you use a function declaration (aka a named function) you can remove the event handler with EventTarget.removeEventListener():
function handleConfirmation(event){
let form = event.target;
event.preventDefault();
swal.fire({
title: 'Are you sure ?',
text: `You are about to spend ${expectedExpenditure()} credits.`,
showCancelButton: true,
}).then((result) => {
if (result.isConfirmed) {
console.log('submitting');
form.removeEventListener('ajax:beforeSend', handleConfirmation);
Rails.fire(form, 'submit');
}
})
}
}
const form = document.getElementById('assign_sessions_to_employees')
form.addEventListener('ajax:beforeSend', handleConfirmation);
Another alternative is to just set a data attribute in your event handler:
const form = document.getElementById('assign_sessions_to_employees')
form.addEventListener(
'ajax:beforeSend',
(event) => {
if (event.target.dataset.confirmed) { return };
event.preventDefault();
swal.fire({
title: 'Are you sure ?',
text: `You are about to spend ${expectedExpenditure()} credits.`,
showCancelButton: true,
}).then((result) => {
if (result.isConfirmed) {
console.log('submitting');
form.dataset.confirmed = true;
Rails.fire(form, 'submit');
}
})
}
)