Reputation: 109
I'd like to display the #LoadingDiv while checkCoupon
is firing, and have it disappear when it finishes, to show the function is in progress. checkCoupon is triggered by a button click (not displayed).
I've tried a variety of things including creating another function to include in onclick
event, I've put this in different parts of the ajax call, and tried altering the CSS in different ways. It's still not working.
Any idea how to get this functionality and have this display properly at the beginning of the call starts?
function checkCoupon() {
var coupon = document.getElementById('couponCode').value;
var coupon_v = false;
$('#LoadingDiv').css('display', 'block');
$.ajax({
type: 'post',
url: 'coupon.php',
async: false,
data: {
'coupon': coupon
},
success: function(data) {
if (data != "empty") {
coupon_v = data;
}
}
})
}
<div id="LoadingDiv" style="display:none;">One Moment Please...<br />
<img src="images/progressbar.gif" class="displayed" alt="" />
</div>
Upvotes: 1
Views: 975
Reputation: 188
I had the same issue. I know this is an older question by now, but obviously still relevant as I ran into the same conundrum.
I would call the showLoadingOverlay()
method which would make the loading div visible, then run the function I wanted to run and then hide the loading overlay, but the overlay would never show. I finally found that the issue was that the function I was performing after showing the loading overlay was happening too quickly and it would pause the process of showing the overlay until it was done and then the hide function on the overlay was being called too quickly afterwards when the show method was able to resume. This is why it appeared that nothing was happening at all.
So, you need to delay the function you are trying to call (I used the setTimeout()
method). The 400 in the setTimeout()
method is 400 miliseconds that will be delayed before performing the processFunction
method. Here is a generic way to accomplish your goal:
Javascript:
/******************************************************************************************
* Toggle loading overlay.
* ***************************************************************************************/
/**
* Toggle the loading overlay in order to prevent the user from performing any actions.
* The processFunction must call the endLoadOverlay method once it is finished.
* @param {any} processFunction The process to perform while the loading screen is active.
* This method must call the endLoadOverlay method once it is done.
*/
function startLoadOverlay(processFunction) {
$('#overlay').css('display', '');
setTimeout(processFunction, 400);
}
/**
* Ends the loading overlay.
* */
function endLoadOverlay() {
$('#overlay').css('display', 'none');
}
/******************************************************************************************
* End of toggle loading overlay.
* ***************************************************************************************/
Then when you call the startLoadOverlay() method pass the method that you want to accomplish through it. In my example I'm having a button click event call the overlay method:
HTML:
<button id="btnDoAction" type="button" onclick="startLoadOverlay(myFunctionToAccomplish);">Accomplish Something</button>
Remember, myFunctionToAccomplish()
is the method that I want performed while the overlay is visible. NOTE: The method that you pass to the startLoadOverlay() method must call the endLoadOverlay()
method after it is done processing in order to hide the loading overlay. So:
Javascript
function myFunctionToAccomplish() {
// Perform functionality.
//TODO: Add whatever functionality here.
// Once I'm done I need to call the endLoadOverlay() method in order to hide the loading overlay.
endLoadOverlay();
}
In case you are curious about my $('#overlay')
element. The idea is basically from here: https://www.w3schools.com/howto/howto_css_overlay.asp
Upvotes: 0
Reputation: 1327
You can make use of jQuery's beforeSend
and complete
methods to address states before and after the call:
function checkCoupon() {
var coupon = document.querySelector('#couponCode').value;
var coupon_v = false;
let $loading = $('#LoadingDiv');
$.ajax({
type: 'post',
url: '.', //coupon.php
async: false,
data: {
'coupon': coupon
},
beforeSend: function() {
$loading.removeClass('hide')
},
success: function(data) {
if (data != "empty") {
coupon_v = data;
}
},
complete: function() {
// timeout only used for demo effect
window.setTimeout(function() {
$loading.addClass('hide')
}, 1500)
}
})
}
.hide {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="LoadingDiv" class="hide">One Moment Please...<br />
<img src="images/progressbar.gif" class="displayed" alt="" />
</div>
<input type="hidden" id="couponCode" value="3" />
<button onclick="checkCoupon()">Click</button>
Upvotes: 1
Reputation: 68913
You can hide the div on ajax complete
function which is called when the request finishes (after the success or error callbacks are executed):
complete: function(){
$('#LoadingDiv').hide();
}
Upvotes: 5