I am showing a progress loader on my webpage when there are some processing going on in the background task. The problem I am facing is that the div which contains progress loader always stays "display : none " on Chrome and IE browser. However it works fine on FF and Safari.
Here is the HTML
<div id="progressIndicatorBackground">
<div id="progressIndicator">
<img src="/cms/images/icons/progressIndicator.gif" alt="Loading...">
</div>
</div>
CSS
#progressIndicatorBackground, #preLoaderBackground {
display: none;
height: auto;
width: auto;
top: 0;
bottom: 0;
right: 0;
left: 0;
z-index: 9000;
position: fixed;
background-color:rgba(0, 0, 0, 0.5);
}
JS function for showing and hiding progress loader
function progressIndicator(value) {
if(value) {
$("#progressIndicatorBackground").show();
}
else {
$("#progressIndicatorBackground").hide();
}
}
On several occasion I am calling the progressIndicator function. For e.g. In one of the page I am calling the function (This is just an example function I am using in my web app. There are other functions as well where I am calling progressIndicator function in the same way)
racingSubCategoryBindClick: function(id, parentId) {
if ($('#'+id).css('display') != 'none') {
$("#"+id).unbind();
$("#"+id).live('click', function() {
// Make all the rest of the group not active, not only this active
$('.' + $(this).attr('class') +'.active').removeClass('active');
$(this).addClass('active');
progressIndicator(true);
var menuId = $(this).parent().parent().attr('id'), day;
if (menuId.indexOf(days.today) != -1) day = days.today
else if (menuId.indexOf(days.tomorrow) != -1) day = days.tomorrow
else day = days.upcoming;
$.when(ajaxCalls.fetchEventsForCategory(id, parentId, day)).done(function (eventsMap) {
// There are no events
if (eventsMap.events.length == 0 || eventsMap.events[0].markets.length == 0) {
$('#mainError').show();
$('div.main').hide();
}
else {
$('#mainError').hide();
$('#'+id).addClass('active');
var events = eventsMap.events;
// If there are events
if (events.length > 0) {
var firstActive = racingNavigation.drawAllRaceNumbers(events);
racingNavigation.drawRaceView(events, firstActive);
// if 1st time and no next selections on the right
if ($('#tabaside').css('display') == 'none') racingNavigation.drawNextRaces(false, true, numberOfNextRaces);
$('.racing_nextraces').hide()
}
$('div.main').show();
}
});
$('.rightmain').show();
$('#racing_home').hide();
progressIndicator(false);
});
}
},
When the background task is in progress and I am fetching JSON data the progress indicator should be visible after calling progressIndicator(true) and as soon as the processing is completed the display attribute should be set to none as I am calling progressIndicator(false) after everything is done. But the status of progressIndicatorBackground is never set display : block on Chrome and IE.
P.S -> I am using latest version or Chrome and IE.
P.S.S -> I have tried modifying my function to but no luck. The problem still persist on Chrome and IE.
function progressIndicator(value) {
if(value) {
$("#progressIndicatorBackground").css("display", "block");
}
else {
$("#progressIndicatorBackground").css("display", "none");
}
}
The main problem was because of using synchronous AJAX calls. It does freezes Chrome and IE and stop any other events to fire up.
Progress loader wasn't working because it was waiting for the synchronous ajax calls to finish loading the event.
Original AJAX call
fetchEventsForCategory: function (categoryId, parentId, day) {
var to = (date.getTo(day) == null) ? '' : '&to=' + date.getTo(day);
return $.ajax({
url: "/billfold-api/betting/events",
type: "POST",
data: 'scid=' + categoryId + '&pcid=' + parentId + '&from=' + date.getFrom(day) + to,
dataType: "json",
async: false,
});
},
Modified AJAX call with success callback
fetchEventsForCategory: function (categoryId, parentId, day) {
var to = (date.getTo(day) == null) ? '' : '&to=' + date.getTo(day);
return $.ajax({
url: "/billfold-api/betting/events",
type: "POST",
data: 'scid=' + categoryId + '&pcid=' + parentId + '&from=' + date.getFrom(day) + to,
dataType: "json",
async: true,
success: function(data) {
progressIndicator(false);
}
});
},
In my JS function where I was calling the progress loader. I removed progressIndicator(false);and instead put it under success function in my ajax call itself.
In my experience display:none can make things buggy and should only be used as a last resort. Take a look at this article here for alternatives. Also I found sometimes adding :hidden helps in making jquery show a hidden or display:none element. So for instance $("#progressIndicatorBackground:hidden").show(); might get it to work.
Related
AJAX call instead of .click load - I would like the ajax to run every 3 seconds till the end of Total_Records. Here is my AJAX code which runs .click of a button.
I am passing two variables
1. id number
2. Total_Records
I would like the ajax to iterate a number of times = Total_Records.
Any suggestions are highly appreciated.
$(document).ready(function() {
$(document).on('click', '.show_more', function() {
var ID = $(this).attr('id');
var lim = $(this).attr('Total_Records');
$.ajax({
type: 'POST',
url: 'moreajax.php',
data: {
'id': ID,
'lim': lim
},
success: function(html) {
setTimeout(function() {
$('#show_more_main' + ID).remove();
$('.postList').append(html);
}, delay);
},
});
});
});
Method 2) Please kindly read and recommend any better way or script improvement with examples please. this will benefit everyone.
Note: I believe this method would be a great enhancement and re-usable to lots of people who are looking for interval runs.
The only issue is the cancel button .click is not stopping the ajax call.
$('#cancel').click(function() {
cancel = true;
});
$(function() {
//If cancel variable is set to true stop new calls
if (cancel == true) return;
var RecordsInterval = 10 * 1000;
var fetchRecords = function() {
console.log('Sending DATA AJAX request...');
$.ajax({
type: "POST",
url: "fetchRecords.php",
data: {
'id': ID,
'lim': lim
}
}).done(function(html) {
$('#show_more_main' + ID).remove();
$('#postList').append(html);
alert("You got it champ")
console.log('success');
console.log('Waiting ' + (RecordsInterval / 1000) + ' seconds');
setTimeout(fetchRecords, RecordsInterval);
}).fail(function() {
console.log('error');
alert("error Champ");
return;
});
}
// Fetch Records immediately, then every 10 seconds AFTER previous request finishes
fetchRecords();
});
I have a function that uses Ajax to get search results in real time, as the user types. It has a check if the input field's length is 1 or more, and if it is then it adds the class 'open' to display the dropdown for the search results. It also has an else statement, where if the length is 0 it removes open. This works fine on my localhost, but on my website if i hold backspace on more than two characters, it won't remove open (If i tap backspace it always works).
$(document).ready(function() {
$("#search").on('input', function() {
if ($('#search').val().length >= 1) {
$.ajax({
type: "POST",
url: "/url",
data: {
"json_str": $('#search').val()
},
dataType: "json",
success: function(data) {
if (!$("#searchbar").hasClass("open")) {
$("#searchbar").addClass("open")
}
if (data.length == undefined) {
$('#display').html("No results")
} else {
for (var i = 0; i < data.length; i++) {
console.log(data[i].username)
$('#display').append("<some html>")
}
}
}
});
} else {
$("#searchbar").removeClass("open")
}
});
})
I have found a solution, I am now aborting the last AJAX call if a new one is made before a response comes in.
var request = null;
$("#search").on('input', function() {
if (request){
request.abort()
}
if ($('#search').val().trim().length >= 1) {
request = $.ajax({.........
Try to trim the input value
if($('#search').val().trim().length)
I have a site in development which uses ajax page loading. This all works as expected except when it comes to images.
If you visit the link below, you will see a page title "Brands" which has an svg icon followed by an img.
Now if you click "Brands" in the sidebar the page will fade out, fetch the same page via the .load method and then fade in the content. However you will notice in Chrome that the svg is seemingly missing. If you check in safari the svg is visible but the img is missing. If you check it in Firefox then you get the alt attribute displayed.
After inspecting the page you will notice that they have a height of 0px and a width of 0px.
Why is happening and how can I resolve it?
http://kga.creativelittledevs.co.uk/consultant/brands/
I did try an create a reduced test case but it wasnt very easy to replicate.
Here's my full ajax code:
Object.defineProperty(String.prototype, "decodeHTML", {
value: function () {
return $('<div>', {html: '' + this}).html();
}
});
var init = function() {
$('select').selectric({
arrowButtonMarkup:'<svg class="selectric__button"><use xlink:href="/images/icons.svg#icon-right-chevron"></use></svg>'
}, 'refresh');
},
ajaxLoad = function(html) {
document.title = html.match(/<title>(.*?)<\/title>/)[1].trim().decodeHTML();
init();
},
loadPage = function(href, get, put) {
$(put).fadeOut(200, function(){
$(put).load(href + ' ' + get, function(){
ajaxLoad;
$(put).fadeIn(200);
});
});
};
init();
$(window).on('popstate', function(e) {
var state = e.originalEvent.state;
if (state !== null) {
loadPage(location.href, state.get, state.put);
} else {
history.pushState({get: '.app-main > *', put: '.app-main'}, '', location.href);
}
});
kga.doc.on('click', '.js-ajax', function() {
var $this = $(this),
href = $this.attr('href'),
get = $this.data('ajax-get') ? $this.data('ajax-get') + ' > *' : '.app-main > *',
put = $this.data('ajax-put') ? $this.data('ajax-put') : '.app-main';
if (href.indexOf(document.domain) > -1 || href.indexOf(':') === -1) {
history.pushState({get: get, put: put}, '', href);
loadPage(href, get, put);
return false;
}
});
Any help would be very much appreciated, thanks.
jQuery / Ajax Add Class to an LI not working. Trying to add the 'open' class to a LI, that opens my 'floating cart' area when an item has been added to the cart. However, the 'open' class just. won't. apply. Not sure why.
I'm also using the Bootstrap framework, and jQuery.
My Code is:
function ShoppingCartAddAJAX(formElement, productNumber) {
formElement = $(formElement);
$.ajax({
type: "POST",
url: "dmiajax.aspx?request=ShoppingCartAddAJAX",
data: formElement.serialize(),
dataType: "json",
success: function (response) {
if (response.Status == "WishListSuccess") {
var url = "productslist.aspx?listName=" + response.listName + "&listType=" + response.listType;
$(location).attr('href', url)
} else if (response.Status == "Success") {
if (response.Status == "Success") {
$.ajax({
type: "GET",
url: "dmiajax.aspx?request=FloatingCart&extra=" + rnd(),
dataType: "html",
success: function (response) {
$('#floating').addClass('open');
var floatingCart = $("ul.dropdown-menu.topcartopen");
if (floatingCart.length == 0) {
floatingCart = $('<ul class="dropdown-menu topcart open"></ul>').insertBefore("#floating-cart");
floatingCart.hoverIntent({
over: function () {},
timeout: 200,
out: function () {
$(this).stop(true, true).filter(":visible").hide("drop", {
direction: "down"
})
}
})
}
floatingCart.html(response);
$("html, body").scrollTop(0);
var floatingCartTbody = floatingCart.find("tbody");
floatingCartTbody.find("tr").filter(":last").effect("highlight", {
color: "#B3B3B3"
}, 3500);
floatingCart.fadeIn()
}
});
if (response.CartItemCount) {
if (response.CartItemCount == "0") {
$("a.cart-tools-total").html("Shopping Cart<span class=\"label label-orange font14\">0</span> - $0.00")
} else {
$("a.cart-tools-total").html("Shopping Cart <span class=\"label label-orange font14\"> " + response.CartItemCount + " Item(s) </span> - " + response.CartItemTotal + " <b class=\"caret\"></b>")
}
}
formElement.find("select option").attr("selected", false);
formElement.find("input:radio").attr("checked", false);
formElement.find("input:checkbox").attr("checked", false);
formElement.find("input:text").val("");
if (formElement.find(".personalization-toggle").length > 0) {
formElement.find(".person-options").hide()
}
if (formElement.find(".attribute-wrap.trait").length > 0) {
formElement.find(".stock-wrap").remove()
}
} else if (response.Error) {
alert(response.Error)
}
}
}
})
}
The line where I'm tring to add it to the LI is:
$('#floating').addClass('open');
The LI is:
<li id="floating" class="dropdown hover carticon cart">
The LI's ID is floating, I figured that'd add the class of 'open' to it. NOPE. For some reason, just not happening.
And, just for the sake of including it, the live environment is here: http://rsatestamls.kaliocommerce.com/
Try changing it to:
$('#floating').attr("class", "open");
Try adding this to your ajax request. It maybe is getting an error:
$.ajax({
type: "GET",
url: "dmiajax.aspx?request=FloatingCart&extra=" + rnd(),
dataType: "html",
success: function (response) {
$('#floating').addClass('open');
var floatingCart = $("ul.dropdown-menu.topcartopen");
if (floatingCart.length == 0) {
floatingCart = $('<ul class="dropdown-menu topcart open"></ul>').insertBefore("#floating-cart");
floatingCart.hoverIntent({
over: function () {},
timeout: 200,
out: function () {
$(this).stop(true, true).filter(":visible").hide("drop", {
direction: "down"
})
}
})
}
floatingCart.html(response);
$("html, body").scrollTop(0);
var floatingCartTbody = floatingCart.find("tbody");
floatingCartTbody.find("tr").filter(":last").effect("highlight", {
color: "#B3B3B3"
}, 3500);
floatingCart.fadeIn()
}
error: function(objAjax,state,exception){
console.log('exception: '+exception+'. State: '+state);
},
});
Then, you will be able to check (at Firebug or other app) if your request is working right.
I suspect you are not correctly selecting the #floating element. Sometimes the element is not visible with only the ID and you must be a little more specific with the selectors.
We would need to see exactly the source for the rendered page to be sure what to put, but try doing this:
Add a button onto the page that you can use to test if you found the correct selector:
<input id="mybutt" type="button" value="Tester Click">
Next, add this javascript/jquery code and -- one at a time -- comment the test selector that failed, and uncomment the next attempt:
$('#mybutt').click(function() {
var test = $("#floating");
//var test = $("li #floating");
//var test = $("ul li #floating");
//var test = $("ul > li #floating");
if ( test.length > 0 ) {
alert('Found this: ' + test.attr('id') );
}
});
Once you are certain that you have the correct selector, then your original code -- using the correct selector -- should work:
$('#the > correctSelector').addClass('open');
Note: the above code uses jQuery, so ensure you are including the jQuery library on the page (usually between the <head> tags, like this:
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
</head>
I've this section of code (I'll point out where I'm confused, just added that huge wall to incase anyone wanted to really dig in).
anyway, the behaviour is to display these boxes, when you click on a box, the box expands, and displays more information. this works 70% of the time, however, it seems when an image is not chached, when you click the box again to minimize it, it starts to minimize, then pops back out. I'm wondering if this has something to do with the line: if($(this)[0].style.width == '70%'){
If this isn't enough, feel free to ask, and if you want to attempt to replicate the issue:
http://newgameplus.nikuai.net/
Try searching a few games, and clicking on the results. (That's only if what I"m saying isn't making sense though)
Thank you.
$container.on("click", ".box", function (event) {
var description;
var user_id;
var org_img = $(this).find("img").attr("src");
if ($(this)[0].style.width == '70%') {
$(this).find("img").attr("src", org_img);
$(this).css('width', '18%');
$(this).find(".resultData").fadeOut('slow');
$container.masonry('reload');
} else {
var me = this;
value['name'] = $(me).find("p").html();
oldImage = $(this).find("img").attr("src");
$.ajax({
url: 'scripts/php/fetchResultsData.php',
data: {
action: value
},
type: 'post',
dataType: 'json',
success: function (data) {
description = data[0][2];
for (var i = 0; i < $test.length; i++) {
if ($test[i][1][2]['name'] == value['name']) {
pos = i;
break;
}
}
$(me).find("img").attr("src", data[0][4]);
$(me).css('width', '70%');
$(me).append("\
<div class='resultData'>\
<div class='resultName'>" + value['name'] + "</div>\
<div class='resultDesc'>" + description + "</div>\
<div class='reasonDataTitle'> Similar tropes between this game and the searched games </div>\
<div class='reasonData'>" + $test[pos][4] + "</div>\
<div class='wikiLink'><a href='http://wikipedia.org/wiki/" + value['name'] + "'>Wikipedia</a></div>\
<div class='resultLike'></div>\
</div>");
value['clicked'] = 0;
$.ajax({
url: 'scripts/php/userProfile.php',
data: {
action: value
},
type: 'post',
dataType: 'json',
success: function (profileData) {
if (profileData == 'alreadyAdded') {
$(me).children('.resultData').children('.resultLike').html('un-Favourite');
} else if (profileData == 'notLoggedIn') {
$(me).children('.resultData').children('.resultLike').html('Login to add');
} else {
$(me).children('.resultData').children('.resultLike').html('Favourite?');
}
}
});
$(me).on("click", '.resultLike', function (event) {
event.stopPropagation()
value['clicked'] = 1;
$.ajax({
url: 'scripts/php/userProfile.php',
data: {
action: value
},
type: 'post',
dataType: 'json',
success: function (profileData) {
if (profileData == 'removed') {
$(me).children('.resultData').children('.resultLike').html('Favourite?');
} else if (profileData == 'notLoggedIn') {
$(me).children('.resultData').children('.resultLike').html('Login to add');
} else {
$(me).children('.resultData').children('.resultLike').html('un-Favourite');
}
}
});
});
$container.masonry('reload');
}
});
}
});
I would suspect there's a race condition in your effects code. jQuery effects run asynchronously, so $container.masonry('reload') will get called when fadeOut starts rather than after it's finished. If the jQuery Masonry plugin affects the display of any blocks you're fading out (and its documentation indicates that's highly possible), that race condition of both functions running at once will cancel the first one out.
To work around this, try running the Masonry reload in a callback function to fadeOut, like so:
$(this).find(".resultData").fadeOut('slow', function () {
$container.masonry('reload');
});
The reason it happens only sometimes is based on the speed of how things are loading, which would explain why it only happens when certain assets aren't cached.