Show Gif on click and Hide after Ajax Success - javascript

I found lots os posts with the solution to my problem, but no one works to me...
I tried like:
<div class="ibox-content">
<div id="carregando" class="text-center" style="display:none">
<img src="~/Imagens/logo.png" />
</div>
<div id="container" style="height: 460px; margin: 0 auto"></div>
</div>
My JS is called on a button clink who calls a funcion like bellow:
$("#atualiza").click(function () {
$(document).ajaxStart(function () {
$("#carregando").show();
});
$.ajax({
url: '/Portaria/AtendOperador',
dataType: "json",
type: "GET",
data: { 'data1': data1, 'data2': data2, 'evento': evento, 'cuc': cuc, 'conta': conta },
async: false,
cache: false,
delay: 15,
success: function (data) {
var Categories = new Array();
var Series = new Array();
for (var i in data) {
Categories.push(data[i].Operador);
Series.push(data[i].Fechados);
}
var CategArray = JSON.parse(JSON.stringify(Categories));
atendOperador(CategArray, Series);
$(document).ajaxStop(function () {
$("#carregando").hide();
});
},
error: function (xhr) {
alert('error');
$(document).ajaxStop(function () {
$("#carregando").hide();
});
}
});
});
function atendOperador(CategArray, Series) {
var chart2 = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'bar'
}
});
}
Even I put the code:
$( document ).ajaxStart(function() {
$( "#carregando" ).show();
});
The image appear only after ajax finishing. Using the two blocks, show and Hide, the image not appear, so, i tried to remove the hide block and i could see that the problem is: Show and Hide happens together when ajax is loaded like:
I cliked on button and noting happened like: http://prntscr.com/ars97n
And after few seconds, Ajax load data and show icon and data together: http://prntscr.com/ars9xq

Try $("#carregando").hide(); instead of $(document).ajaxStop(function ()$("#carregando").hide();});
edit: ajaxStart and ajaxEnd are event handlers. I think they should be registered outside of the click function. Something like this:
$(document).ready(function(){
$(document).ajaxStart(function () {
$("#carregando").show();
});
$(document).ajaxStop(function () {
$("#carregando").hide();
});
$("#atualiza").click(function () {
/* all your code here except for the ajaxStart/ajaxStop portion */
});
});

As Karl stated, the best way to do it is without using ajaxStart/ajaxStop event handlers, or even better, without using jQuery at all.
document.querySelector('.get-data').addEventListener('click', function() {
document.querySelector('.display-data').textContent = null;
document.querySelector('.loading').style.display = 'block';
var request = new XMLHttpRequest();
request.open('GET', 'http://jsonplaceholder.typicode.com/photos', true);
request.onload = function() {
if (this.status >= 200 && this.status < 400) {
// Success!
var data = JSON.parse(this.response);
document.querySelector('.loading').style.display = 'none';
document.querySelector('.display-data').textContent = JSON.stringify(data[0]);
} else {
// We reached our target server, but it returned an error
document.querySelector('.loading').style.display = 'none';
}
};
request.onerror = function() {
// There was a connection error of some sort
document.querySelector('.loading').style.display = 'none';
};
request.send();
});
<button class="get-data">Get Data</button>
<div class="loading" style="display: none">
<img src="https://upload.wikimedia.org/wikipedia/commons/2/28/InternetSlowdown_Day.gif" width="50px">
</div>
<div class="display-data"></div>

Finally! I found the problem here! All ways I tried before works now, with this modification I did.
Just:
$("#carregando").show();
Or:
$(document).ajaxStart(function () {
$("#carregando").show();
});
$(document).ajaxStop(function () {
$("#carregando").hide();
});
Or:
beforeSend: function() {
$("#carregando").show();
},
complete: function() {
$("#carregando").hide();
},
All my problem were here: http://prntscr.com/asbxbk!!!
So, I commented that async and works!!!
$("#atualiza").click(function () {
$(document).ajaxStart(function () {
$("#carregando").show();
});
$(document).ajaxStop(function () {
$("#carregando").hide();
});
$.ajax({
url: '/Portaria/AtendOperador',
dataType: "json",
type: "GET",
data: { 'data1': data1, 'data2': data2, 'evento': evento, 'cuc': cuc, 'conta': conta },
//async: false, COMMENTED!!!
success: function (data) {
var Categories = new Array();
var Series = new Array();
for (var i in data) {
Categories.push(data[i].Operador);
Series.push(data[i].Fechados);
}
var CategArray = JSON.parse(JSON.stringify(Categories));
atendOperador(CategArray, Series);
},
error: function (xhr) {
alert('error');
}
});
});

Karl's answer is correct if you want to show the same git for all ajax request on the page
But if you want to do it for this particular AJAX the follow this
$("#atualiza").click(function () {
$.ajax({
beforeSend: function() { $("#carregando").show(); }, //It will show the gif just before sending the request
url: '/Portaria/AtendOperador',
dataType: "json",
type: "GET",
data: { 'data1': data1, 'data2': data2, 'evento': evento, 'cuc': cuc, 'conta': conta },
async: false,
cache: false,
delay: 15,
success: function (data) {
var Categories = new Array();
var Series = new Array();
for (var i in data) {
Categories.push(data[i].Operador);
Series.push(data[i].Fechados);
}
var CategArray = JSON.parse(JSON.stringify(Categories));
atendOperador(CategArray, Series);
$("#carregando").hide(); //this will hide the gif in case of AJAX success
},
error: function (xhr) {
alert('error');
$("#carregando").hide(); //this will hide the gif in case of AJAX failure
}
});
});
Hope this will help you

Related

How to load data from ajax to zabuto calendar plugin?

As title, I tried load data from ajax to zabuto calendar, but seem it's not working, ref of zabuto calendar http://zabuto.com/dev/calendar/examples/show_data.html. And i want to use this function load data when click nav prev month or next month. (use two action action and action_nav). This is snipped code
<script>
$(document).ready(function () {
function load_data() {
var list = '';
$.ajax({
type: "POST",
url: "../BUS/WebService.asmx/LOAD_DATA",
contentType: "application/json; charset=utf-8",
dataType: "json",
cache: false,
success: function (data) {
list = $.parseJSON(data.d);
console.log(list);
}
});
return list;
}
function myNavFunction(id) {
//code in here
}
function myDateFunction(id) {
//code in here
}
$("#my_calendar").zabuto_calendar({
data: load_data(),
action: function () {
return myDateFunction(this.id);
},
action_nav: function () {
return myNavFunction(this.id);
}
});
});
</script>
When i test this, data not show, the data from ajax as
{ "date": "2016-06-01", "title": 2, "badge": true },{ "date": "2016-06-04", "title": 1, "badge": true },{ "date": "2016-06-10", "title": 1, "badge": true }
Thank you so much.
Try the following: you need to place the calendar function in the success function of the ajax call because ajax is asynchronous
$(document).ready(function () {
function load_data() {
$.ajax({
type: "POST",
url: "../BUS/WebService.asmx/LOAD_DATA",
contentType: "application/json; charset=utf-8",
dataType: "json",
cache: false,
success: function (data) {
var list = $.parseJSON(data.d);
$("#my_calendar").zabuto_calendar({
data: list;
});
},
error: function (data) {
console.log(data.d);
}
});
}
load_data();
});
I solved the issue by the code as below. It works well in window's browser but not in a mobile browser.
function initZabuto(id, events, month){
$('#zabuto_parent').empty().append("<div id='"+id+"'></div>");
$("#"+id).zabuto_calendar({
year:moment(month).format("YYYY"),
month:moment(month).format("MM"),
language:"cn",
data: events,
action: function () {
zabutoDayClick(this.id);
},
action_nav: function () {
zabutoMonthChange(this.id);
}
});
}
This is the code I used to refresh Zabuto calendar after a modal. The problem with other options is that upon refresh, Zabuto would create a new batch of modals appended to the current body. This solutions clears all those "old" modals and opens room for the new. Key area is the success section of the modal update ajax.
$(document).ready(function () {
$("#date-popover").popover({html: true, trigger: "manual"});
$("#date-popover").hide();
$("#date-popover").click(function (e) {
$(this).hide();
});
load_calendar();
});
function load_calendar() {
$("#my-calendar").zabuto_calendar({
show_next: 1,
action: function () {
return myDateFunction(this.id, false);
},
ajax: {
url: "calendar-info.php",
modal: true
},
});
}
function myDateFunction(id, fromModal) {
$("#date-popover").hide();
if (fromModal) {
$("#" + id + "_modal").modal("hide");
var date = $("#" + id).data("date");
var optradio = $("#" + id + "_modal").find("input[name='optradio']:checked").val();
$.ajax("calendar-update.php?status="+optradio+"&date="+date, {
success: function(data) {
$(".modal").remove();
$('body').removeClass('modal-open');
$('.modal-backdrop').remove();
$("#my-calendar").empty();
load_calendar();
},
error: function() {
alert("Problem!");
}
});
}
var hasEvent = $("#" + id).data("hasEvent");
if (hasEvent && !fromModal) {
return false;
}
return true;
}

Jquery $(this).closest('form'); not working after button click

I have the following js code:
$("#add_station").on('click', function () {
$(this).closest('form').submit(function () {
alert("working!");
$.ajax({
url: advoke.base_url + "/new-vendor-user/station/ajax",
method: 'post',
processData: false,
contentType: false,
cache: false,
dataType: 'json',
data: new FormData(this),
beforeSend: function () {
$('.info').hide().find('ul').empty();
$('.success_message').hide().find('ul').empty();
$('.db_error').hide().find('ul').empty();
},
success: function (data) {
if (!data.success) {
$.each(data.error, function (index, val) {
$('.info').find('ul').append('<li>' + val + '</li>');
});
$('.info').slideDown();
setTimeout(function () {
$(".info").hide();
}, 5000);
} else {
$('.success_message').slideDown();
$('#add_station').remove();
$("#station").append(data.new_station);
setTimeout(function () {
$(".success_message").hide();
}, 5000);
} //success
},
error: function () {
//db error
$('.db_error').append('<li>Something went wrong, please try again!</li>');
$('.db_error').slideDown();
//Hide error message after 5 seconds
setTimeout(function () {
$(".db_error").hide();
}, 5000);
} //error
});
});
return false;
});
When I click the button with the id add_station it alerts on click function after $($this).closest('form').submit(function(){...) it doesn't work as you can see I've put an alert 'works' after submit function.I get no errors on the console and I can't figure what the problem is. Also, the button that is clicked is inside a form.
I need to use $($this).closest('form').submit(function(){...) inside because after ajax success a new form will be generated with add station button that will use this code.
You should block the default submit trigger by using
e.preventDefault();
$(this).closest('form').submit(function (e) {
e.preventDefault();
<!--rest of the code-->
})
add a separately submit handler
$("#add_station").on('click', function () {
$(this).closest('form').submit();
});
$("form").on("submit", function (e) {
e.preventDefault();
alert("working!");
$.ajax({
url: advoke.base_url + "/new-vendor-user/station/ajax",
method: 'post',
processData: false,
contentType: false,
cache: false,
dataType: 'json',
data: new FormData(this),
beforeSend: function () {
$('.info').hide().find('ul').empty();
$('.success_message').hide().find('ul').empty();
$('.db_error').hide().find('ul').empty();
},
success: function (data) {
if (!data.success) {
$.each(data.error, function (index, val) {
$('.info').find('ul').append('<li>' + val + '</li>');
});
$('.info').slideDown();
setTimeout(function () {
$(".info").hide();
}, 5000);
} else {
$('.success_message').slideDown();
$('#add_station').remove();
$("#station").append(data.new_station);
setTimeout(function () {
$(".success_message").hide();
}, 5000);
} //success
},
error: function () {
//db error
$('.db_error').append('<li>Something went wrong, please try again!</li>');
$('.db_error').slideDown();
//Hide error message after 5 seconds
setTimeout(function () {
$(".db_error").hide();
}, 5000);
} //error
});
});
after ajax success a new form will be generated with add station
button that will use this code
If you generate a new button you have to bind the click again after it is placed to the dom.

Ajax, prevent multiple request on click

I'm trying to prevent multiple requests when user click on login or register button. This is my code, but it doesn't work. Just the first time works fine, then return false..
$('#do-login').click(function(e) {
e.preventDefault();
if ( $(this).data('requestRunning') ) {
return;
}
$(this).data('requestRunning', true);
$.ajax({
type: "POST",
url: "/php/auth/login.php",
data: $("#login-form").serialize(),
success: function(msg) {
//stuffs
},
complete: function() {
$(this).data('requestRunning', false);
}
});
});
Any ideas? Thanks!
The problem is here:
complete: function() {
$(this).data('requestRunning', false);
}
this no longer points to the button.
$('#do-login').click(function(e) {
var me = $(this);
e.preventDefault();
if ( me.data('requestRunning') ) {
return;
}
me.data('requestRunning', true);
$.ajax({
type: "POST",
url: "/php/auth/login.php",
data: $("#login-form").serialize(),
success: function(msg) {
//stuffs
},
complete: function() {
me.data('requestRunning', false);
}
});
});
Use on() and off(), that's what they are there for :
$('#do-login').on('click', login);
function login(e) {
e.preventDefault();
var that = $(this);
that.off('click'); // remove handler
$.ajax({
type: "POST",
url: "/php/auth/login.php",
data: $("#login-form").serialize()
}).done(function(msg) {
// do stuff
}).always(function() {
that.on('click', login); // add handler back after ajax
});
});
In your ajax callbacks the context (this) changes from the outer function, you can set it to be the same by using the context property in $.ajax
$.ajax({
type: "POST",
url: "/php/auth/login.php",
data: $("#login-form").serialize(),
context: this, //<-----
success: function(msg) {
//stuffs
},
complete: function() {
$(this).data('requestRunning', false);
}
});
You can disable the button.
$(this).prop('disabled', true);
I have also faced a similar problem.
Just adding $('#do-login').attr("disabled", true); gives me the solution.
$('#do-login').click(function(e) {
e.preventDefault();
$('#do-login').attr("disabled", true);
.........
.........
Here do-login is button id.
I've tried this and worked very fine for me, I was having trouble that $.ajax send more request until results return,
var settings = {
"url": "/php/auth/login.php",
"method": "POST",
"timeout": 0,
"async": false,
"headers": {
"Content-Type": "application/json; charset=utf-8"
},
"data": jsondata, //data pass here is in JSON format
};
$.ajax(settings).done(function (ress) {
try{
console.log(ress, "Result from Ajax here");
}
catch(error){
alert(error);
console.log(ress);
}
});
async : false worked for me.
Thanks.
Or you can do it by $(this).addClass("disabled"); to you button or link and after click is performed, you can $(this).removeClass("disabled");.
// CSS
.disabled{
cursor: not-allowed;
}
// JQUERY
$('#do-login').click(function(e) {
e.preventDefault();
$(this).addClass("disabled");
$.ajax({
type: "POST",
url: "/php/auth/login.php",
data: $("#login-form").serialize(),
context: this,
success: function(msg) {
//do more here
$(this).removeClass("disabled");
},
});
});
P.S. If you use bootstrap css, you do not need the css part.
I found the approach useful. I've implemented it as a general purpose function for jQuery with ES6.
export default function (button, promise) {
const $button = $(button);
const semaphore = 'requestRunning';
if ($button.data(semaphore)) return null;
$button.data(semaphore, true);
return promise().always(() => {
$button.data(semaphore, false);
});
}
Because $.ajax() returns a promise, you simply pass in the promise and the function takes care of the rest.
Roughly speaking, here's the usage.
import preventDoubleClick from './preventdoubleclick';
...
button.click(() => {
preventDoubleClick(this, () => $.ajax()
.done(() => { console.log("success") }));
});
This function can help you with control multi Ajax requests and it's has timeout function which can return flag status to 0 after ex. 10sec (In case the server took more than 10 seconds to respond)
var Request_Controller = function(Request_Name = '', Reactivate_Timeout = 10000)
{
var a = this;
a.Start_Request = function(){
if(window.Requests == undefined){
window.Requests = {};
}
window.Requests[Request_Name] = {'Status' : 1, 'Time': + new Date()};
}
a.End_Request = function(){
if(window.Requests == undefined){
window.Requests = [];
}
window.Requests[Request_Name] = undefined;
}
a.Is_Request_Running = function(){
if(window.Requests == undefined || window.Requests[Request_Name] == undefined){
return 0;
}else{
var Time = + new Date();
// Reactivate the request flag if server take more than 10 sec to respond
if(window.Requests[Request_Name]['Time'] < (Time - Reactivate_Timeout))
{
return 0;
}else{
return 1
}
}
}
}
To use it:
var Request_Flag = new Request_Controller('Your_Request_Name');
if(!Request_Flag.Is_Request_Running()){
Request_Flag.Start_Request();
$.ajax({
type: "POST",
url: "/php/auth/login.php",
data: $("#login-form").serialize(),
success: function(msg) {
//stuffs
},
complete: function() {
Request_Flag.End_Request();
}
});
}
for prevent multiple ajax request in whole site. For example: If use ajax request in other ajax page, Using ajax in php loop, etc, Give you multiple ajax request with one result. I have solution:
Use window.onload = function() { ... }
instead of
$(document).ready(function(){ ... });
on the main index.php page. Its will be prevent all multi request. :)

TypeError: this.functionName is not a function

So I have created a small javascript class that is supposed to AJAX post something in a PHP file. The class is the following:
var cms = cms || {};
cms.load_view = (function() {
return {
change: function() {
jQuery("#layout-switch a").on('click', function()
{
jQuery('#layout-switch a').removeClass('current');
jQuery(this).addClass('current');
var column_number = jQuery(this).attr('data-name');
var category = jQuery("#cat_id").val();
var data = {mode: column_number, cid: category};
this.postChange(data);
});
},
postChange: function(data) {
jQuery.ajax({
type: 'post',
url: SITEURL + "/modules/digishop/loadcategory.php",
data: data,
beforeSend: function () {
jQuery('#digishop').animate({
opacity: 0
}, 250, function () {
jQuery(this).addClass(column_number);
jQuery(this).animate({
opacity: 1
}, 250);
});
},
success: function (html) {
jQuery("#digishop").html(html);
}
});
return true;
}
}
})(jQuery);
jQuery(document).ready(function() {
cms.load_view.change();
});
However, when I click the selector Firebug says that postChange is not a function when it is called in the first method, a.k.a. this.postChange(data);
Any ideas?
Thanks!
Inside the change function, this is a reference to the link you clicked. Replace this.postChange(data); with cms.load_view.postChange(data);.

loading image during delay

I got the delay to work when you click on the buttons but I cant get the loading gif to display during the delay.
Thanks
function () {
$('.sectionThreeTab:not(.tabActive)').click(function () {
$('ajax-loader.gif').bind('ajaxStart', function () {
$(this).show();
}).bind('ajaxStop', function () {
$(this).hide();
});
$('.tabActive').removeClass('.tabActive');
$(this).addClass('tabActive');
var lesson = $(this).attr('lesson');
var self = $(this);
setTimeout(function () {
$.ajax({
type: "GET",
url: 'lessons/' + lesson + '.htm',
datatype: "json",
success: function (data) {
$('#sectionTabContent').append(data);
}
})
}, 3000);
return false;
});
}
You can try this instead of what you have:
Delete this part:
$('ajax-loader.gif').bind('ajaxStart', function () {
$(this).show();
}).bind('ajaxStop', function () {
$(this).hide();
});
And change the setTimeout to this:
setTimeout(function () {
$("#loading").show();
$.ajax({
type: "GET",
url: 'lessons/' + lesson + '.htm',
datatype: "json",
success: function (data) {
$('#sectionTabContent').append(data);
},
complete: function() {
$("#loading").hide();
}
})
}, 3000);
Please also post your html so we can see if everything else is in order.
Edit:
<div id="loading" class="grayBackground withBorder10" style="display:none">
<img alt="Loading..." src="img/ajax-loader.gif" />
</div>
I believe your targeting the loading image incorrectly, try:
$('#ajaxLoader').bind('ajaxStart', function () {
$(this).show();
}).bind('ajaxStop', function () {
$(this).hide();
});
Where your loading image has an Id #ajaxLoader (replace to suit your HTML).

Categories