I have page in my application that displays status. The status is displayed in drop down menu with two options Active/Inactive
. The user can change the status by simply clicking on the menu and choosing the option. For that process I use JQuery/Ajax onchange
trigger to track status change. The code is working fine and saves the value in datatbase. The issue I’m experiencing is related to bootbox
and displaying loading message. When user clicks on the menu and changes the status ajax will send the request. At that point dialog window will show on the user screen with the loading message. Once ajax request is complete loading dialog should hide and display message tot he user that status successfully saved. Here is the code example:
function alertBox(title, message, size) {
title = title || "Alert";
message = message || "Alert Box";
size = size || "lg";
bootbox.alert({
size: size,
title: title,
message: message
});
};
$('.status').on('change', function() {
let $curr_fld = $(this),
status_id = $curr_fld.attr('data-id'),
dialog = bootbox.dialog({
message: '<p class="text-center mb-0"><i class="fa fa-spin fa-cog"></i> Loading...</p>',
closeButton: false
});
$curr_fld.prop("disabled", true);
/*** Start: This is a code for testing. ***/
/*
setTimeout(function() {
dialog.modal('hide');
$curr_fld.prop("disabled", false);
alertBox('Alert Message', status_id);
}, 3000);
*/
/*** End: This is a code for testing. ***/
$.ajax({
type: 'POST',
url: 'test.php?id=1',
data: {
'status_id': status_id
},
dataType: 'json'
}).done(function(obj) {
dialog.modal('hide');
$curr_fld.prop("disabled", false);
if (obj.status === 200) {
alertBox('Alert Message', obj);
} else {
alertBox('Alert Message', obj);
}
}).fail(function(jqXHR, textStatus, errorThrown) {
$curr_fld.prop("disabled", false);
alertBox('Error', textStatus);
});
});
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootbox.js/5.4.0/bootbox.min.js"></script>
<table class="table table-striped table-bordered" id="tbl_nofa">
<thead>
<tr class="bg-dark">
<th class="text-center text-white">Section</th>
<th class="text-center text-white">Status</th>
</tr>
</thead>
<tbody>
<tr>
<td class="text-center"> South</td>
<td class="text-center">
<select class="custom-select status" name="status_1" id="status_1" data-id="1">
<option value="A" selected>Active</option>
<option value="I">Inactive</option>
</select>
</td>
</tr>
<tr>
<td class="text-center"> North</td>
<td class="text-center">
<select class="custom-select status" name="status_2" id="status_2" data-id="2">
<option value="A">Active</option>
<option value="I" selected>Inactive</option>
</select>
</td>
</tr>
<tr>
<td class="text-center"> East</td>
<td class="text-center">
<select class="custom-select status" name="status_3" id="status_3" data-id="3">
<option value="A" selected>Active</option>
<option value="I">Inactive</option>
</select>
</td>
</tr>
<tr>
<td class="text-center"> West</td>
<td class="text-center">
<select class="custom-select status" name="status_4" id="status_4" data-id="4">
<option value="A">Active</option>
<option value="I" selected>Inactive</option>
</select>
</td>
</tr>
</tbody>
<tfoot>
<tr class="bg-dark">
<th class="text-center text-white">Section</th>
<th class="text-center text-white">Status</th>
</tr>
</tfoot>
</table>
If you run code example above, you will see once the ajax request is complete loading dialog is still on the screen. I’m not sure why since I have .modal('hide')
in place. If you comment out the block of code with setTimeout and comment out the ajax code you will see that loading dialog works just fine. If anyone knows how to solve this issue please let me know.
2
Answers
I noticed a couple of issues:
always
function of your ajax call. When testing the fail would occur, but you had no code to close the dialog. However this still didn’t fix the problem.This appears to be an issue with the boostrap modal. What’s happening is that the
hide
function is being called too soon before the animation completes. There are two solutions to work around this issue:animate: false
.always
function.There might be more succinct ways to handle the animation issue without disabling the animation itself. This was just one method.
As per Daniel Gimenez, the issue is that
dialog.modal('close')
get’s called very soon a easy fix to this will be to usesetTimeout()
, this will allow you to keep those fancy animations also:Replace all
dialog.modal('hide')
withHence your complete code will be: