adding a delay to changing an image attr after an ajax request - javascript

so i have a function that is triggered a click of a button (imagine a published/unpublished button)
so as soon as the function loads i change the element to be a loader gif
function updateStatus(event, status, element, data, action) {
//init loader
$("#" + element).find("img").attr("src", "../../img/images/loader.gif");
that works fine
then I do an ajax request where i pass the data (so i can update the database via the rest)
var request= $.ajax({
type: 'get',
url: "../testResponses/status.php",
data:data
});
again that is all good and then when the request is done I can change the image
request.done(function(msg) {
$("#" + element).find("img").attr("src", "../../img/images/status/"+newStatus+".png");
$("#" + element).attr("data-user-status", newStatus);
});
seeing as this is still a proof of concept I want to add a 2 second delay before the loader image disappears and the new status us shown
I tried
request.delay(2000).done ...
which returned an error and
$("#" + element).delay(2000).find("img").attr("src", "../../img/images/status/"+newStatus+".png");
which just didnt make any difference..
can anyone help?

You can use setTimeout() to trigger the logic in 2 seconds after you get the request:
request.done(function(msg) {
setTimeout(function(){
// change the image
}, 2000);
});

Another solution is to use the .delay() queue
$("#" + element).delay(2000).delay(function (next) {
$(this).find("img").attr("src", "../../img/images/status/" + newStatus + ".png");
next();
});

Related

The code in the Ajax done method doesn't recognize the code thats already loaded

So I am trying to make a dynamic system where a button changes when you click on another button. For instance, when you click on the button: "12+4", different buttons will appear at another div. I use an append method for that. But when you click on one of the "patroon" buttons, it will not execute the $(".tile").on('click', function). That is because that code is already executed before the ajax call. My code is below:
arr.forEach(function (value, key) {
$("#row2").append('<button class="dikte" data-value="' + key + '">' + value + '</button>')
});
$(".dikte").on('click', function () {
let dataVal = $(this).data('value');
// Code...
$.ajax({
url: "Api/getObjectGroepen.php",
type: 'GET',
beforeSend: function () {
// $(".spinner-border").removeClass("d-none");
},
success: function () {
// $(".spinner-border").addClass("d-none");
}
}).done(function (data) {
$("#row3").html("");
$(arrObjectGroep).each(function (key, value) {
$("#row3").append('<button class="btn tile" data-value="' + value + '">' + JSON.parse(data)[value] + '</button>')
});
});
});
// Tile section
$(".tile").on("click", function (e) {
// Prevents button from executing
e.preventDefault();
// execute code
console.log(123);
});
So the $(".tile") are all the buttons. And $(".dikte") is the "12+4" button.
Hopefully someone understands my problem about what is going on, it's maybe a bit hard to explain, but I can explain further if there are any questions. Is there a clean and simple solution for this? Rather than moving all the code to the done method.
Jquery doesn't know the button's which you appended dynamically, for that your code should be like below, and which will rescan the document to find the element with the class name
$(document).on('click','.tile',function(e){
// code
});

Ajax wont call when output from another ajax

I have comment system using live ajax php, and also include for vote system on that comment
Logic: when i post new comment, system will call ajax function with method post, and display response in above of textarea for comment, that response is include vote system (a class="with_unique_id"), but when i click that vote, it wont calling ajax function (nothing happend in browser console), whereas in current comment that displaying in above of new comment, it working fine.
This is my ajax code for vote
jQuery(document).ready(function($){
$(".voteMe").click(function() {
var voteId = this.id;
var upOrDown = voteId.split('_');
$.ajax({
type: "post",
url: "<?php echo base_url('blog/likepost');?>/"+upOrDown[0],
cache: false,
data:'voteId='+upOrDown[0] + '&upOrDown=' +upOrDown[1],
success: function(response){
try{
if(response=='true'){
var newValue = parseInt($("#"+voteId+'_result').text()) + 1;
$("#"+voteId+'_result').html(newValue);
document.getElementById('likeStatus_'+upOrDown[0]).innerHTML = 'Success';
$("#likeStatus_"+upOrDown[0]).show();
setTimeout(function() { $("#likeStatus_"+upOrDown[0]).hide(); }, 5000);
}else{
$("#likeStatus_"+upOrDown[0]).show();
document.getElementById('likeStatus_'+upOrDown[0]).innerHTML = 'Liked';
setTimeout(function() { $("#likeStatus_"+upOrDown[0]).hide(); }, 5000);
}
}catch(err) {
alert(err.message);
}
},
error: function(){
alert('Error while request..');
}
});
});
});
It took me a while to read your code, but I guess this is the root cause:
if(response=='true'){
var newValue = parseInt($("#"+voteId+'_result').text()) + 1;
$("#"+voteId+'_result').html(newValue);
document.getElementById('likeStatus_'+upOrDown[0]).innerHTML = 'Success';
$("#likeStatus_"+upOrDown[0]).show();
setTimeout(function() { $("#likeStatus_"+upOrDown[0]).hide(); }, 5000);
}
This line here:
$("#"+voteId+'_result').html(newValue);
That become the link you want to click again. Right?
If that is so, then you need to re-assign the event handler.
By replacing the DOM element, you have also removed the assigned event handler
PS: You code is very hard to read. It will be nightmare for you to maintain it.
i have fixed my code with adding same ajax code function in response of current ajax with different id.
thankyou

Loading Spinner Image too fast at start of Function

I have a function that displays contents of a posts when clicked on. I want the loading spinner to display and delay for few sections before the post content appears. The issue here is when I click on each post, the spinner appears for maybe 1ms and in some cases it disappears long before the content appears.
function showPost(id) {
setTimeout(function() {$('#loader').show();},1);
$('#pcontent').empty();
$.getJSON('http://howtodeployit.com/category/daily-devotion/?json=get_post&post_id=' + id + '&callback=?', function(data) {
var $postcon = $('<div/>').append([$("<h3>", {html: data.post.title}),$("<p>", {html: data.post.content})]);
$postcon.appendTo('#pcontent');
});
}
Spinner HTML:
<div id='loader'><img src="css/images/loader.gif"/></div>
Try this:
function showPost(id) {
$('#loader').show();
$('#pcontent').empty();
$.ajax({
url: 'http://howtodeployit.com/category/daily-devotion/?json=get_post&post_id=' + id + '&callback=?',
dataType: 'json',
success: function (data) {
var $postcon = $('<div/>').append([$("<h3>", {
html: data.post.title
}), $("<p>", {
html: data.post.content
})]);
$postcon.appendTo('#pcontent');
$('#loader').hide();
}
});
}
gif image always behave differently on every device..basically it depends upon device's processing speed. so better option is to use image sprites and animate it with javascript..
In your case at page load there is nothing processing..but as page starts to load device's processor cant handle the load and as a result your gif image gets slower
It seems from your last commented line that you are using a timeout to hide the loader. Instead You should handle the hiding inside the callback function of your ajax request, so that loader hides after request is completed, not after a fixed amount of time:
function showPost(id) {
$('#loader').show();
$('#pcontent').empty();
$.getJSON('http://howtodeployit.com/category/daily-devotion/?json=get_post&post_id=' + id + '&callback=?', function(data) {
$('#loader').hide();
var $postcon = $('<div/>').append([$("<h3>", {html: data.post.title}),$("<p>", {html: data.post.content})]);
$postcon.appendTo('#pcontent');
});
}

jquery refresh content in a div

I have 2 divs in an HTML page -that need refreshing when an event is triggered.
One of the divs, if display:none and will not refresh with the new data.
Is it not possible to refresh display:none divs?
My JavaScript is below,
$('#messages_send').live('click', function() {
$.ajax({
url: base_url + 'ajax/send_message',
data: {
username: $('#messages_username').val(),
message: $('#messages_message').val(),
saveid: $('#messages_savedid').val(),
},
success: function(data) {
sending_message();
var x = jQuery.parseJSON(data);
if(x) {
if(x.gp_id==80)
{
$('#spn_ucredit').load(base_url + 'ajax/userdata/credits');
$('#overlay_credits').load(base_url + 'ajax/userdata/credits');
}
}
//$('#spn_ucredit').html($('#ncd_id').val());
//tmp_cost = $('#spn_ucredit').html()-$('#ncd_id').val();
//$('#ncd_id').val($('#ncd_id').val()-tmp_cost);
//alert(data);
setTimeout(message_sent, 2000);
setTimeout(remove_modal_box, 3000);
setTimeout(message_revert, 3500);
$("#saved_messages").load(base_url + 'messages #saved_messages > form');
//setTimeout($("#messages_content").load(base_url + 'messages #messages_content > form'), 1000);
//$.get(base_url + 'messages #saved_messages > form', null, function(result){ $("#saved_messages").html(result) });
//$("#messages_content").css("visibility","hidden").show();
//$.get(base_url + 'messages #messages_content > form', null, function(result){ $("#messages_content").html(result) });
//$("#messages_content").css("visibility","visible").hide();
}
});
return false;
});
using .hide() lets a div be edited , while setting display:none makes it a lot harder
"The matched elements will be hidden immediately, with no animation. This is roughly equivalent to calling .css('display', 'none'), except that the value of the display property is saved in jQuery's data cache so that display can later be restored to its initial value. If an element has a display value of inline, then is hidden and shown, it will once again be displayed inline."
So if it's important that you're able to revert to the previous value of display, you'd better use hide() because that way the previous state is remembered. Apart from that there's no difference.
from resource on jQuery's .hide() Here
Also , there are SO questions on this as well - Here's an example of one

How to show processing animation / spinner during ajax request?

I want a basic spinner or processing animation while my AJAX POST is processing. I'm using JQuery and Python. I looked at the documentation but can't figure out exactly where to put the ajaxStart and ajaxStop functions.
Here is my js:
<script type="text/javascript">
$(function() {
$('.error').hide();
$("#checkin-button").click(function() {
var mid = $("input#mid").val();
var message = $("textarea#message").val();
var facebook = $('input#facebook').is(':checked');
var name = $("input#name").val();
var bgg_id = $("input#bgg-id").val();
var thumbnail = $("input#thumbnail").val();
var dataString = 'mid='+mid+'&message='+message+'&facebook='+facebook+'&name='+name+'&bgg_id='+bgg_id+'&thumbnail='+thumbnail;
$.ajax({
type: "POST",
url: "/game-checkin",
data: dataString,
success: function(badges) {
$('#checkin-form').html("<div id='message'></div><div id='badges'></div>");
$('#message').html("<h2><img class=\"check-mark\" src=\"/static/images/check-mark.png\"/>You are checked in!</h2>");
$.each(badges, function(i,badge) {
$('#badges').append("<h2>New Badge!</h2><p><img class='badge' src='"+badge.image_url+"'><span class='badge-title'>"+badge.name+"</span></p>");
});
}
});
return false;
});
});
</script>
$.ajax({
type: "POST",
url: "/game-checkin",
data: dataString,
beforeSend: function () {
// ... your initialization code here (so show loader) ...
},
complete: function () {
// ... your finalization code here (hide loader) ...
},
success: function (badges) {
$('#checkin-form').html("<div id='message'></div><div id='badges'></div>");
$('#message').html("<h2><img class=\"check-mark\" src=\"/static/images/check-mark.png\"/>You are checked in!</h2>");
$.each(badges, function (i, badge) {
$('#badges').append("<h2>New Badge!</h2><p><img class='badge' src='" + badge.image_url + "'><span class='badge-title'>" + badge.name + "</span></p>");
})
}
});
http://api.jquery.com/jQuery.ajax/:
Here are the callback hooks provided by $.ajax():
beforeSend callback is invoked; it receives the jqXHR object and the settings map as parameters.
error callbacks are invoked, in the order they are registered, if the request fails. They receive the jqXHR, a string indicating the error type, and an exception object if applicable. Some built-in errors will provide a string as the exception object: "abort", "timeout", "No Transport".
dataFilter callback is invoked immediately upon successful receipt of response data. It receives the returned data and the value of dataType, and must return the (possibly altered) data to pass on to success.
success callbacks are then invoked, in the order they are registered, if the request succeeds. They receive the returned data, a string containing the success code, and the jqXHR object.
complete callbacks fire, in the order they are registered, when the request finishes, whether in failure or success. They receive the jqXHR object, as well as a string containing the success or error code.
Note the beforeSend and complete method additions to the code.
Hope that helps.
If you're using jQuery 1.5 you could do that nicely, unobtrusively and generically with a prefilter. Let's make a very simple plugin for this:
(function($) {
var animations = {};
$.ajaxPrefilter(function( options, _, jqXHR ) {
var animation = options.animation && animations[ options.animation ];
if ( animation ) {
animation.start();
jqXHR.then( animation.stop, animation.stop );
}
});
$.ajaxAnimation = function( name, object ) {
if ( object ) {
animations[ name ] = object;
}
return animations[ name ];
};
})( jQuery );
You install an animation as follows:
jQuery.ajaxAnimation( "spinner" , {
start: function() {
// code that starts the animation
}
stop: function() {
// code that stops the animation
}
} );
then, you specify the animation in your ajax options:
jQuery.ajax({
type: "POST",
url: "/game-checkin",
data: dataString,
animation: "spinner",
success: function() {
// your success code here
}
});
and the prefilter will ensure the "spinner" animation is started and stopped when needed.
Of course, that way, you can have alternative animations installed and select the one you need per request. You can even set a default animation for all requests using ajaxSetup:
jQuery.ajaxSetup({
animation: "spinner"
});
The best method I have found, assuming you are populating a present but empty field is to have a .loading class defined with background-image: url('images/loading.gif') in your CSS. You can then add and remove the loading class as necessary with jQuery.
you can set global ajax loading icon handler using here #ajxLoader takes your loading icon
$( document ).ajaxStart(function() {
$("#ajxLoader").fadeIn();
});
$( document ).ajaxComplete(function() {
$("#ajxLoader").fadeOut();
});
$(function() {
$('.error').hide();
$("#checkin-button").click(function() {
var mid = $("input#mid").val();
var message = $("textarea#message").val();
var facebook = $('input#facebook').is(':checked');
var name = $("input#name").val();
var bgg_id = $("input#bgg-id").val();
var thumbnail = $("input#thumbnail").val();
var dataString = 'mid=' + mid + '&message=' + message + '&facebook=' + facebook + '&name=' + name + '&bgg_id=' + bgg_id + '&thumbnail=' + thumbnail;
$.ajax({
type : "POST",
url : "/game-checkin",
data : dataString,
beforeSend : function() {
$('#preloader').addClass('active');
},
success : function(badges) {
$('#preloader').removeClass('active');
$('#checkin-form').html("<div id='message'></div><div id='badges'></div>");
$('#message').html("<h2><img class=\"check-mark\" src=\"/static/images/check-mark.png\"/>You are checked in!</h2>");
$.each(badges, function(i, badge) {
$('#badges').append("<h2>New Badge!</h2><p><img class='badge' src='" + badge.image_url + "'><span class='badge-title'>" + badge.name + "</span></p>");
});
},
complete : function() {
$('#preloader').removeClass('active');
}
});
return false;
});
});
#preloader{
background: url(staticpreloader.gif);
}
.active {
background: url(activepreloader.gif);
}
I wrote a blog post about how to do this on a generic document level.
// prepare the form when the DOM is ready
$(document).ready(function() {
// Setup the ajax indicator
$('body').append('<div id="ajaxBusy"><p><img src="images/loading.gif"></p></div>');
$('#ajaxBusy').css({
display:"none",
margin:"0px",
paddingLeft:"0px",
paddingRight:"0px",
paddingTop:"0px",
paddingBottom:"0px",
position:"absolute",
right:"3px",
top:"3px",
width:"auto"
});
});
// Ajax activity indicator bound to ajax start/stop document events
$(document).ajaxStart(function(){
$('#ajaxBusy').show();
}).ajaxStop(function(){
$('#ajaxBusy').hide();
});
The AJAX process starts when you run the $.ajax() method, and it stops when the 'complete' callback is run. So, start your processing imagery/notification right before the $.ajax() line, and end it in the 'complete' callback.
ajaxStart and ajaxStop handlers can be added to any elements, and will be called whenever ajax requests start or stop (if there are concurrent instances, start only gets called on the first one, stop on the last to go). So, it's just a different way of doing global notification if you had, for example, a status spinner somewhere on the page that represents any and all activity.

Categories

Resources