this is my first question, please be gentle :) I've been trying to resolve this for a couple of hours now and I'm getting nowhere fast.
Background
I have a web application where a process is kicked off with .ajax(). This can take a little while to complete, so I have set up a jQuery.progressbar() system to give UI feedback that is started (using setInterval) at the same time as the .ajax(), and every 250ms it calls a .getJSON() to read the progress of the background event. Everything server-side seems to function flawlessly.
The Problem
It seems that (from copious use of console.log() that the .ajax() event blocks the .getJSON() from running, until the .ajax() has completed. In my console log I have every 250ms an indication that updateProgressBar() is running, but I never get into the .done portion of it until the original .ajax() call finishes.
What am I missing here?
// file copy dialog
$(function () {
$("#file_copy_dialog").dialog({
autoOpen: false,
resizable: false,
height: 250,
width: 400,
modal: true,
buttons: {
"Copy Files": function () {
// do ajax copy request
console.log("Starting setInterval updateProgressBar()");
window.interval = setInterval('updateProgressBar()', 250);
console.log("---------------------------------- Firing file_copy AJAX request ---------------------------------");
$.ajax({
type: "POST",
url: "/ajax/file_copy.php",
data: {
job_id: "<?php echo $item_data['job_id']; ?>",
item_id: "<?php echo $item_id; ?>",
quote_id: "<?php echo $item_data['quote_id']; ?>"
}
})
.done(function () {
console.log("----------------------------- file_copy AJAX done --------------------------------------");
});
},
"Cancel": function () {
$(this).dialog("close");
}
}
});
});
// paste button click event handler
$(function () {
$("#paste_files").click(function () {
// open dialog box
$("#progressbar").progressbar({
value: 0
});
$(".progress-label").text("Ready");
$("#file_copy_dialog").dialog("open");
});
});
// progress bar initiator
$(function () {
var progressbar = $("#progressbar"),
progressLabel = $(".progress-label");
progressbar.progressbar({
value: false,
change: function () {
progressLabel.text(progressbar.progressbar("value") + "%");
},
complete: function () {
progressLabel.text("Complete!");
}
});
});
// file copy progress checker
function updateProgressBar() {
console.log("Running updateProgressBar()");
$.getJSON("/ajax/file_copy_progress.php")
.done(function (json) {
console.log("In UpdateProgressBar().done");
// successful check
if (json.status == 'ERROR') {
console.log("updateProgressBar() json.status = ERROR");
$('#progresstext').text(json.message);
clearInterval(window.interval);
} else {
console.log("updateProgressBar() json.status = " + json.status + " json.value = " + json.value);
$('#progressbar').progressbar({
value: json.value
});
$('#progresstext').text(json.message);
}
if (json.value == 100) {
console.log("ClearInterval()");
clearInterval(window.interval);
}
})
.fail(function (jqxhr, textStatus, error) {
// check failed
$('#progresstext').text("Progress check request failed");
});
}
Forgive my formatting ... and thank you for any help you may be able to provide.
EDIT
Thanks to Adeneo, turns out there's nothing wrong with the above code at all. The issue lies with PHP locking the session file. Calling session_write_close() and session_start() in strategic places in your initial backend ajax() called' script, will allow the second script to get a look-in occasionally and read the status.
The issue lies with PHP, not jQuery in this instance.
As pointed out by #adeneo, only one process can read/write the session file at once. (Quite logical when you think about it!). Calling
session_write_close()
and then
session_start()
in strategically good places in your initial script, will permit the first script to get a go at reading the session variables occasionally, and make the whole thing work as intended.
Related
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
I have a following javascript function mixed with MVC controller actions calls:
var loadPartialChapterAfterAnswer = function () {
$.ajax({
url: '#Url.Action("IsAuthenticated", "Story")',
type: "POST",
success: function(data) {
var isAuthenticated = data;
if (isAuthenticated) {
if ('#Model.IsPersonality' == 'True') {
loadPartialChapter();
} else {
$("#chapterContainer").load('#Url.Action("GetNextQuestion", "Story")' + '?storyId=' + '#Model.Id', function () {
selectedCounter = 0;
showOnlyOneQuestion();
});
}
} else {
window.location.href = '#Url.Action("RedirectToHomeRoute", "Home")';
}
},
error: function() {
alert("Error");
}
});
};
Every time I select one checkbox on my page(view) this function is called. Code works great in all browsers except in IE. In IE the ajax url #Url.Action("IsAuthenticated", "Story") is called OK every time, but the other controller action '#Url.Action("GetNextQuestion", "Story")' + '?storyId=' + '#Model.Id' is called only when the IE's browser debugger is turned on. When IE's debugger window is off this second MVC action is never called.
Any help is highly appreciated!
SOLUTION
I added at the beginning of my page this code:
<script>
$.ajaxSetup({
cache: false
});
</script>
and now it works! Thanks all for your effort.
I read something about IE having issues with JQuery load function
Try to replace it with regular $.ajax with cache: false option hopefully it will resolve the issue.
Check this topic
Add controller to this: #Url.Action("GetNextQuestion")'
Without controller specified it place controller which return view last.
I am using jquery mobile auto complete , Please see the demo at http://jsfiddle.net/Q8dBH/11/.
So whenever user press any letter,i need to show some message like "please wait."
So i added some code like below.But its showing only 1st time or 2nd time or not showing at all some times..How to show message whenever user types something until server responds back with data.
$ul.html('<center>Searching Please Wait<br><img src="http://freegifts.in/diet/themes/images/ajax-loader.gif"></center>');
my full js is below.
$(document).on("pagecreate", ".ui-responsive-panel", function () {
$(document).on("click", "li", function () {
var text = $(this).text();
$(this).closest("ul").prev("form").find("input").val(text); });
$("#autocomplete").on("filterablebeforefilter", function (e, data) {
var $ul = $(this),
$input = $(data.input),
value = $input.val(),
html = "";
$ul.html("");
if (value && value.length >0) {
$ul.html('<center>Searching Please Wait<br><img src="http://freegifts.in/diet/themes/images/ajax-loader.gif"></center>');
//$ul.listview("refresh");
$('.ui-responsive-panel').enhanceWithin();
$.ajax({
url: "http://freegifts.in/diet/calorie.php",
dataType: "jsonp",
crossDomain: true,
data: {
q: $input.val()
}
})
.then(function (response) {
$.each(response, function (i, val) {
html += "<li data-role='collapsible' data-iconpos='right' data-shadow='false' data-corners='false'><h2>Birds</h2>" + val + "</li>";
});
$ul.html(html);
//$ul.listview("refresh");
//$ul.trigger("updatelayout");
$('.ui-responsive-panel').enhanceWithin();
});
}
});
});
Working example: http://jsfiddle.net/Gajotres/Q8dBH/12/
Now this is a complex question. If you want to show jQuery Mobile AJAX loader there's one prerequisite, AJAX call must take longer then 50 ms (jQuery Mobile dynamic content enhancement process time will not get into account). It works in jsFiddle example but it may not work in some faster environment.
You can use this code:
$.ajax({
url: "http://freegifts.in/diet/calorie.php",
dataType: "jsonp",
crossDomain: true,
beforeSend: function() {
// This callback function will trigger before data is sent
setTimeout(function(){
$.mobile.loading('show'); // This will show ajax spinner
}, 1);
},
complete: function() {
// This callback function will trigger on data sent/received complete
setTimeout(function(){
$.mobile.loading('hide'); // This will hide ajax spinner
}, 1);
$.mobile.loading('hide'); // This will hide ajax spinner
},
data: {
q: $input.val()
}
})
beforeSend callback will trigger AJAX loader and complete callback will hide it. Of course this will work only if AJAX call lasts more then 50ms. Plus setTimeout is here because jQuery Mobile AJAX loader don't work correctly when used with web-kit browsers, it is a triggering workaround.
I'm Using Web service using AJAX Call In My HTML Page . Web Service Returning Data Nearly 30 to 40 second's .
During This Loading Time I Need to Use Some Loading Gif Images After Data Completely Received Form Web Service The Loading Image Must Be Hide.
I'm Using Only HTML,JAVASCRIPT,CSS,J Query.
Any Idea Or Samples Needed.
I'm Using Following Code
$(document).ready(function () {
document.write('<img src="http://www.esta.org.uk/spinner.gif">');
});
$( window ).load(function() {
//This following Function Related To My Design
jQuery(".chosen").data("placeholder", "Select Frameworks...").chosen();
var config = {
'.chosen-select': {},
'.chosen-select-deselect': { allow_single_deselect: true },
'.chosen-select-no-single': { disable_search_threshold: 10 },
'.chosen-select-no-results': { no_results_text: 'Oops, nothing found!' },
'.chosen-select-width': { width: "95%" }
}
for (var selector in config) {
$(selector).chosen(config[selector]);
}
});
In The Above Code My Problem Is On Page Load Gif Image Show But It's Not Hide Only Gif Image Only Showing.
Put a hidden image on your page and as soon as your ajax call is made, make that image visible
$('#image').show();
$.ajax({
complete: function(){
$('#image').hide();
}
});
and hide that image again on Complete of Ajax call.
Use your ajax request callback (on success/failure) instead of page load.
When sending the request just show a gif animation by setting the Display to block
then when you have the data set the display to none
or use jquery
function showHourGlass()
{
$("#gifimage").show();
}
function hideHourGlass()
{
$("#gifimage").hide();
}
You ask for ideas, I have one sample -
http://www.myntra.com/shoes
load scroll down fastly this is the ajax jquery request which is exact output which you have mentioned in your question
Check source code
Jquery Ajax loading image while getting the data
This what the html looks like:
<button id="save">Load User</button>
<div id="loading"></div>
and the javascript:
$('#save').click(function () {
// add loading image to div
$('#loading').html('<img src="http://preloaders.net/preloaders/287/Filling%20broken%20ring.gif"> loading...');
// run ajax request
$.ajax({
type: "GET",
dataType: "json",
url: "https://api.github.com/users/jveldboom",
success: function (d) {
// replace div's content with returned data
// $('#loading').html('<img src="'+d.avatar_url+'"><br>'+d.login);
// setTimeout added to show loading
setTimeout(function () {
$('#loading').html('<img src="' + d.avatar_url + '"><br>' + d.login);
}, 2000);
}
});
});
I hope this will help you.
I had a question regarding Ajax loading of html into a DIV. Ideally what I want is this:
A toggle div with close button, which I have the code for here: http://jsfiddle.net/tymeJV/uhEgG/28/
$(document).ready(function () {
$('#country').click(function () {
$("#country_slide").slideToggle(function() {
if ($(this).is(":visible")) {
alert("im visible!");
}
});
});
$('#close').click(function (e) {
e.preventDefault();
$('#country_slide').slideToggle();
});
});
Then I want some AJAX code to load a html file into the div when the div is expanded. The trick is that if the HTML is loaded successfully, I want it to avoid reloading the HTML file again if the div is closed and repoened, since I have already loaded it, and just simply toggle the content in and out with the button. The code I have for this (which I got help on from here is this):
http://jsfiddle.net/spadez/uhEgG/55/
$(function () {
$('#country_link').on('click', function (e) {
// Prevent from following the link, if there is some sort of error in
// the code before 'return false' it would still follow the link.
e.preventDefault();
// Get $link because 'this' is something else in the ajax request.
var $link = $(this);
// Exit if the data is loaded already
if ($link.data('loaded') === true)
return false;
$.ajax({
type: 'GET',
dataType: 'html',
url: '/ajax/test.html',
timeout: 5000,
beforeSend: function () {
},
success: function (data, textStatus) {
$("#country_slide").html(data);
alert('request successful');
// If successful, bind 'loaded' in the data
$link.data('loaded', true)
},
error: function (xhr, textStatus, errorThrown) {
$("#country_slide").html('Error');
},
complete: function () {
},
});
});
});
I haven't been able to get this working yet though. So my question is, is it actually possible to do this, and if it is, can anyone with more experience with jquery please help me integrate the div toggle with the ajax loading script.
This is one of my first jquery scripts and I am having a bit of a hard time with it, perhaps it is not for beginners. Thank you.
I edited the fiddle you posted adding the call to slideToogle() where appropriate. Also added a div element to hold the loaded html code.
<div id="country_slide">
Close
<div class=".content"></div> <!-- This is the div I added -->
</div>
You can check the log messages in the console to verify that the code is doing what you expect. The URL for the Ajax call you were doing always returned an error so I changed to the URL that jsfiddle provides for testing: /echo/html/.
Here's the modified JS code:
$(function () {
$('#close').click(function (e) {
e.preventDefault();
$('#country_slide').slideToggle();
});
$('#country_link').on('click', function (e) {
e.preventDefault();
var $link = $(this);
// Exit if the data is loaded already
if ($link.data('loaded') === true) {
console.log('Not using Ajax.');
$("#country_slide").slideToggle();
return false;
}
$.ajax({
type: 'GET',
dataType: 'html',
url: '/echo/html/',
timeout: 5000,
beforeSend: function () {
$("#country_slide .content").html('<p>Loading</p>')
},
success: function (data, textStatus) {
console.log('Fecthed with Ajax.');
$("#country_slide .content").html(data);
$("#country_slide").slideToggle();
// If successful, bind 'loaded' in the data
$link.data('loaded', true)
},
error: function (xhr, textStatus, errorThrown) {
alert('request failed');
},
complete: function () {
},
});
});
});