My question has part solutions on this site but not a complete answer.
On my wordpress homepage I display a counter of the number of questions answered within our webapp. This is displayed using jQuery and AJAX to retrieve the question count from a php file and works fine with this code.
jQuery(document).ready(function() {
function load() {
jQuery.get('/question_count.php', function(data) {jQuery('#p1').html( data ); });
}
load();
setInterval(load,10000);
});
Is there a way to display counting up to the new number retrieved rather than just immediately displaying it?
Something like this?
function countTo(n) {
var p = $("#p1"),
c = parseInt(p.html(), 10) || 0,
dir = (c > n ? -1 : 1); // count up or down?
if (c != n) {
p.html((c + dir) + "");
setTimeout(function() {
countTo(n);
}, 500);
}
}
Call it in your success handler
jQuery.get('/question_count.php', function(data) {
var n = parseInt(data, 10);
countTo(n);
});
Example
You will need to do a setInterval event so that the count up is visable to human eyes.
This may be a problem if you eventually reach enough questions where the count takes a long time to reach the end.
Code will look like this:
function load(){
jQuery.get('/question_count.php', function(data){
var curr = 0;
var max = parseInt(data);
var interval = setInterval(function(){
if(curr==max){
clearInterval(interval);
}
jQuery('#p1').html( curr );
curr+=1; //<-- if the number of questions gets very large, increase this number
},
10 //<-- modify this to change how fast it updates
});
}
}
Related
We are using the following countdown function on our bidding site.
setInterval(function(){
$(".countdown").each(function(){
var seconds = $(this).data('seconds');
if(seconds > 0) {
second = seconds - 1;
$(this).data('seconds', second)
var date = new Date(null);
date.setSeconds(second);
$(this).html(date.toISOString().substr(11, 8))
}
else
{
$(this).html("Finished");
alert('finished');
}
});
}, 1000);
we pass the number of seconds where we want the counter to appear (sometimes more than once on our page:
echo "<div id=\"".$auctionid."\" class=\"countdown\" data-seconds=\"".$diff."\"></div>";
So far it should be clear an it works. Now we have a situation where when someone bids somewhere on the site - the time left for auction is prolonged for 15 seconds, which is written to mysql.
$diff variable is calculated from mysql end time, and it's passed to jQuery on page load.
The question is how to check the mysql time for that auction and sync it in jQuery counter? We had the idea to maybe check every 5 seconds and after it reaches zero to make sure it's over? Any suggestions?
It should look nice to the user.
EDIT:
This is what we have so far:
$(".countdown").each(function() {
var countdown = $(this);
var auctionid = $(this).attr('id');
var interval = setInterval(function() {
var seconds = countdown.data("seconds");
if( seconds > 0 ) {
var second = --seconds;
var date = new Date(null);
date.setSeconds(second);
countdown.data("seconds", second).html(date.toISOString().substr(11, 8))
} else {
// countdown.html("Finished <img src=\"loading.gif\" class=\"tempload\">");
startUpdateingTimeFromDatabase(auctionid);
countdown.html("Finished");
clearInterval(interval);
}
}, 1000);
});
function startUpdateingTimeFromDatabase(auctionid) {
$.getJSON("timer.php?auctionid="+auctionid, function(response) {
// console.log(response.seconds);
$(".countdown#"+auctionid).data("seconds", response.seconds);
if( response.seconds > 0 ) {
// setTimeout(startUpdateingTimeFromDatabase(auctionid), 1000);
} else {
}
});
}
This simply isn't doing what we need it to do. We need to update the seconds (query startUpdateingTimeFromDatabase) every time it reaches zero. Now I think there are two approaches. First is simply return seconds via startUpdateingTimeFromDatabase function and then do everything in the main function, second is update the div via startUpdateingTimeFromDatabase. I think first will be better but I simply can't find a way to do it properly.
Any help is appreciated. Thanks.
You store the seconds left in the elements data. So why not fetch the remaining time maybe via ajax and just pass the new seconds to the elements? Within the next interval run all times will be updated.
Something like this:
$.get("yourGetRemainingTimeScript.php", {auctionId: 1}, function(response) {
$(".countdown").data("seconds", response.seconds);
});
How you check and get the remaining time is up to you. You can set the time for all everywhere again.
$(".countdown").data("seconds", 1337);
Another hint from my side: don't loop all elements with each in the setInterval. Create the intervals inside the loop once. Then your script doesn't need to search every second again over and over for the elements.
And clear the interval when it's finished.
$(".countdown").each(function() {
var countdown = $(this);
var interval = setInterval(function() {
// do your stuff ...
// when finished stop the interval
if( finished ) {
clearInterval(interval);
}
}, 1000);
});
Full working example.
I have an ul with 9 li elements. I want to load some information to these li elements through ajax in asynch mode.
It's so simple, isn't it?
I just created a for(i = 1; i<=9; i++) loop, and called the $.post.
Fail: i will be always 10, because the for loop running more faster, then the $.post. So let's search the $.post in loop on net.
I found three solutions. Two are here, and one is here.
All of it has the same effect: does not works asynchronously. Every time it load the first, then second, then third etc... Sometimes the order is changing, but every request wait while the previous finish.
I am using WIN 10 64bit, Apache 2.4 64 bit, php 5.6 64bit. Already tried on debian box, effect is the same.
In my php file, there is a sleep(1) and an echo 'a'.
My first attempt:
$('.chartContainer').each(function(index,obj) {
var cnt = index + 1;
$.post(getBaseUrl() + 'ajax.php', {dateTime: $('#chart_' + cnt).data('time'), action: 'getChartByDateTime'}, function (reponse) {
$(obj).html(reponse);
});
});
My second attempt:
for (var i = 1; i <= 9; i++) {
(function (i) {
var $obj = $('#chart_' + i);
$.post(getBaseUrl() + 'ajax.php', {dateTime: $('#chart_' + i).data('time'), action: 'getChartByDateTime'}, function (reponse) {
$($obj).html(reponse);
});
})(i);
}
My third attempt:
function loadResponse(i) {
var $obj = $('#chart_' + i);
$.post(getBaseUrl() + 'ajax.php', {dateTime: $('#chart_' + i).data('time'), action: 'getChartByDateTime'}, function (reponse) {
$($obj).html(reponse);
});
}
$(function () {
for (i = 1; i<=9; i++) {
loadResponse(i);
}
});
Expected result:
Every 9 li loaded in 1 second in the same time.
Can somebody lead me to the right solution?
EDIT
Maybe I was not clear. In the production, the script will run for approx. 3 seconds. If I send one request to get all the data back, then it will take 9*3 = 27 seconds while the response arrives. This is why I want to send 9 request, and get back all the data in 3 seconds. I think this is why we use threads.
What I want is to get all the data for all li in the "same" time. Not one by one, or get all in one request.
EDIT 2
Ok guys, shame on me, I think I mislead all of you. There is a session start in my php script.
If I remove everything, and then just echo something and die after sleep. In this case 5 request is responding in 1 sec, other 4 is later. But I think that is a new thred.
From the jQuery manual:
By default, all requests are sent asynchronously (i.e. this is set to true by default). If you need synchronous requests, set this option to false. Cross-domain requests and dataType: "jsonp" requests do not support synchronous operation. Note that synchronous requests may temporarily lock the browser, disabling any actions while the request is active.
Are you sure the requests are not sent by your browser? It is possible your php script does not allow multiple sessions. Have you tried inspecting the ajax calls with firebug/chrome inspector?
Edit:
PHP writes its session data to a file by default. When a request is made to a PHP script that starts the session (session_start()), this session file is locked. What this means is that if your web page makes numerous requests to PHP scripts, for instance, for loading content via Ajax, each request could be locking the session and preventing the other requests from completing.
The other requests will hang on session_start() until the session file is unlocked. This is especially bad if one of your Ajax requests is relatively long-running.
Possible solutions:
Do not use sessions when you don't need them
Close your session after reading/writing the necessary information:
session_write_close();
Store your sessions in Redis/mySQL for example
function loadResponse(i) {
var $obj = $('#chart_' + i);
$.post(getBaseUrl() + 'ajax.php', {dateTime: $('#chart_' + i).data('time'), action: 'getChartByDateTime'}, function (reponse) {
$($obj).html(reponse);
if(i<=9) loadResponse(++i);
});
}
var i = 1;
$(function () {
loadResponse(i);
});
Here loadResponse function is being called first time at the page load. Then it is being called recursively on the response of the POST request.
You can try this.
for (var i = 1; i <= 9; i++) {
var $obj = $('#chart_' + i);
var time = $('#chart_' + i).data('time');
(function ($obj, time) {
$.post(getBaseUrl() + 'ajax.php', {dateTime: time, action: 'getChartByDateTime'}, function (reponse) {
$obj.html(reponse);
});
})($obj, time);
}
Try sending all the data at once
var dateTime = [];
$('.chartContainer').each(function(index,obj) {
var cnt = index + 1;
dateTime.push({date:$('#chart_' + cnt).data('time'),el:'#chart_' + cnt});
});
$.post(getBaseUrl() + 'ajax.php', {dateTime:dateTime , action: 'getChartByDateTime'}, function (reponse) {
$.each(reponse,function(i,v){
$(v.el).html(v.procesedData);
});
});
php :
$ajaxresponse =[];
foreach($_POST['dateTime'] as $datetime) {
$data = $datetime['date'];//change this with your results
$ajaxresponse[]= array('procesedData'=>$data,'id'=>$datetime['id'])
}
return json_encode($ajaxresponse);
I added this shout box from http://www.saaraan.com/2013/04/creating-shout-box-facebook-style
a live demo of it can be seen here http://www.saaraan.com/2013/04/creating-shout-box-facebook-style
I have everything working properly except the slider itself. Every time I try to scroll up, it automatically scrolls back down. It wont stay in the up position. I think the problem is here.
// load messages every 1000 milliseconds from server.
load_data = {'fetch':1};
window.setInterval(function(){
$.post('shout.php', load_data, function(data) {
$('.message_box').html(data);
var scrolltoh = $('.message_box')[0].scrollHeight;
$('.message_box').scrollTop(scrolltoh);
});
}, 1000);
//method to trigger when user hits enter key
$("#shout_message").keypress(function(evt) {
if(evt.which == 13) {
var iusername = $('#shout_username').val();
var imessage = $('#shout_message').val();
post_data = {'username':iusername, 'message':imessage};
//send data to "shout.php" using jQuery $.post()
$.post('shout.php', post_data, function(data) {
//append data into messagebox with jQuery fade effect!
$(data).hide().appendTo('.message_box').fadeIn();
//keep scrolled to bottom of chat!
var scrolltoh = $('.message_box')[0].scrollHeight;
$('.message_box').scrollTop(scrolltoh);
//reset value of message box
$('#shout_message').val('');
More specifically here
var scrolltoh = $('.message_box')[0].scrollHeight;
$('.message_box').scrollTop(scrolltoh);
and here
//keep scrolled to bottom of chat!
var scrolltoh = $('.message_box')[0].scrollHeight;
$('.message_box').scrollTop(scrolltoh);
I have changed the 0 to 1 and other numbers and it fixes the scroll to work right but it doesn't show the latest shout, it will show shout 25 which is the last shout to be seen before deletion. Im not sure if this makes any sense but any help would be great.
The first link from top shows the whole code, the second link shows the example
Try this code, I didn't tested it. I hope it will work.
window.setInterval(function() {
$.post( 'shout.php', load_data, function( data ) {
var old_data = $(".message_box").html();
if ( old_data != data ) {
$(".message_box").html( data );
// get scrollHeight
var scrollHeight = $(".message_box").get(0).scrollHeight,
// get current scroll position
scrollTop = $(".message_box").scrollTop(),
// calculate current scroll percentage
percentage = Math.round( ( 100 / scrollHeight ) * scrollTop );;
// make sure user is not scrolled to top
if ( percentage > 80 ) {
$(".message_box").scrollTop( scrollTop );
}
}
});
}, 1000);
Background Info
I'm fiddling around with some PHP and AJAX at the moment, to try and get the code working for an auto refreshing div (every 10 seconds), that contains comments.
Here is javascript code I am using to refresh the div..
<script type="text/javascript">// <![CDATA[
$(document).ready(function() {
$.ajaxSetup({ cache: false });
setInterval(function() {
$('#content_main').load('/feed_main.php');
}, 5000);
});
// ]]></script>
The code that will populate the div called "content_main", which is in feed_main.php, essentially accesses the database and echo's out the latest comments ...
Question
Is it possible, to only load the div "content_main" if the data inside of it, hasn't changed since the last time it was loaded?
My logic
Because I'm relatively new to javascript and AJAX I don't quite know how to do this, but my logic is:
For the first time it is run..
load data from feed_main.php file
Create a unique value (perhaps a hash value? ) to identify say 3 unique comments
Every other time it is run...
load the data from feed_main.php file
create a NEW unique value
check this value with the previous one
if they're the same, don't refresh the div, just leave things as they are, but if they're different then refresh..
The reason why I want to do this is because the comments usually have pictures attached, and it is quite annoying to see the image reload every time.
Any help with this would be greatly appreciated.
I've faced similar problem not too long ago, i assume that you using mysql or something for your comments storage serverside ?
I solved my problem by first adding timestamp integer column to my mysql table, then when i added a new row, i'd just simply use time() to save the current time.
mysql row insert example:
$query = "INSERT INTO comments (name, text, timestamp) VALUES ('". $name ."', '". $text ."',". time() .");";
step two would be to json_encode the data you sending from serverside:
$output = array();
if ($html && $html !== '') { // do we have any script output ?
$output['payload'] = $html; // your current script output would go in this variable
}
$output['time'] = time(); // so we know when did we last check for payload update
$json = json_encode($output, ((int)JSON_NUMERIC_CHECK)); // jsonify the array
echo $json; // send it to the client
So, now instead of pure html, your serverside script returns something like this:
{
"payload":"<div class=\"name\">Derpin<\/div><div class=\"msg\">Foo Bar!<\/div>",
"time":1354167493
}
You can grab the data in javascript simply enough:
<script type="text/javascript"> // <![CDATA[
var lastcheck;
var content_main = $('#content_main');
pollTimer = setInterval(function() {
updateJson();
}, 10000);
function updateJson() {
var request = '/feed_main.php?timestamp='+ (lastcheck ? lastcheck : 0);
$.ajax({
url: request,
dataType: 'json',
async: false,
cache: false,
success: function(result) {
if (result.payload) { // new data
lastcheck = result.time; // update stored timestamp
content_main.html(result.payload + content_main.html()); // update html element
} else { // no new data, update only timestamp
lastcheck = result.time;
}
}
});
}
// ]]> </script>
that pretty much takes care of communication between server and client, now you just query your database something like this:
$timestamp = 0;
$where = '';
if (isset($_GET['timestamp'])) {
$timestamp = your_arg_sanitizer($_GET['timestamp']);
}
if ($timestamp) {
$where = ' WHERE timestamp >= '.$timestamp;
}
$query = 'SELECT * FROM comments'. $where .' ORDER BY timestamp DESC;';
The timestamps get passed back and forth, client always sending the timestamp returned by the server in previous query.
Your server only sends comments that were submitted since you checked last time, and you can prepend them to the end of the html like i did. (warning: i have not added any kind of sanity control to that, your comments could get extremely long)
Since you poll for new data every 10 seconds you might want to consider sending pure data across the ajax call to save substantial chunk bandwidth (json string with just timestamp in it, is only around 20 bytes).
You can then use javascript to generate the html, it also has the advantage of offloading lot of the work from your server to the client :). You will also get much finer control over how many comments you want to display at once.
I've made some fairly large assumptions, you will have to modify the code to suit your needs. If you use my code, and your cat|computer|house happens to explode, you get to keep all the pieces :)
How about this:
<script type="text/javascript">
// <![CDATA[
$(function () {
function reload (elem, interval) {
var $elem = $(elem);
// grab the original html
var $original = $elem.html();
$.ajax({
cache : false,
url : '/feed_main.php',
type : 'get',
success : function (data) {
// compare the result to the original
if ($original == data) {
// just start the timer if the data is the same
setTimeout(function () {
reload(elem, interval)
}, interval);
return;
}
// or update the html with new data
$elem.html(data);
// and start the timer
setTimeout(function () {
reload(elem, interval)
}, interval);
}
});
}
// call it the first time
reload('#content_main', 10000);
});
// ]]>
</script>
This is just an idea to get you going it doesn't deal with errors or timeouts.
Best And Easy Code
setInterval(function()
{
$.ajax({
type:"post",
url:"uourpage.php",
datatype:"html",
success:function(data)
{
$("#div").html(data);
}
});
}, 5000);//time in milliseconds
This question already has an answer here:
How to paginate query results for Infinite Scroll?
(1 answer)
Closed 8 years ago.
Infinite scroll should stop after 10 rows of records. If there are more records, ajax pagination should be displayed. For example, consider this infinite scrolling example.
So after 20 records I want to display pagination and same should be done on next page. Please let me know if you have any of this ideas or solution.
Here is my code on which I am working:
//On doMouseWheel = 1 I have taken the currentdealoffset value and check it with the total no of deals present
//If count is less, then simply calculating the window position displaying the allotted records say 10
//On next scroll just doing the same process and fetching records using ajax until end of the deals
//Now the problem is I am not able to code a logic where after say 10 records show a pagination and
//When click on next page the same process should be managed by fetching the offset count of scrol and offset of pagination bar
doMouseWheel = 1 ;
$(window).scroll(function() {
if($('#facebox_overlay').is(':visible')==false){
$('#endofdeals').show();
$('#endofdeals').html("<center><img src='"+SITEIMG +"ajax-loader_1.gif' ><center>");
//console.log("Window Scroll ----");
var currentdealoffset = 0; //alert(currentdealoffset);
var currentdealoffset = parseInt(document.getElementById("countval").value); //alert(currentdealoffset);
var displaymode = parseInt($('#displaymode').val());
var totalcountdeal = parseInt($('#totaldeals').val()); //alert(totalcountdeal);
if(currentdealoffset<totalcountdeal){
if (!doMouseWheel) {
return ;
} ;
var distanceTop = $('#last').offset().top - $(window).height();
if ($(window).scrollTop() > distanceTop){
//console.log("Window distanceTop to scrollTop Start");
doMouseWheel = 0 ;
$('div#loadMoreComments').show(5000);
//console.log("Another window to the end !!!! "+$(".postedComment:last").attr('id'));
$.ajax({
type : 'POST',
dataType : "html",
data: {
typeday : $('#remdumtype').val(),
catid : $('#catid').val(),
},
url: "<?php echo https_url($this->config->item('base_url'))?>popup/dealsearch",
success: function(html) {
doMouseWheel = 1;
if(html){
if(displaymode==12)
$('#listTable tr:last').after(html);
else
$("#postedComments").append(html);
//console.log("Append html--------- " +$(".postedComment:first").attr('id'));
//console.log("Append html--------- " +$(".postedComment:last").attr('id'));
$("#last").remove();
$("#postedComments").append( "<p id='last'></p>" );
$('div#loadMoreComments').hide();
$('#endofdeals').hide();
}
}
});
}
}
else
{
if($('#endofdeals')!='')
{
$('#endofdeals').hide();
if(currentdealoffset < displaymode)
{
$('#endofdeals').hide();
}else if(currentdealoffset > displaymode)
{
$('#endofdeals').show();
$('#endofdeals').html("<center><h2 style='color:#4C335B'>End of deals !!!!!!!</h2></center>");
}
}
}
}
});
According to me, You want page numbers but the pages should load slowly as you scroll.
If this you want then, you should not use Infinite scroll technique but LazyScroll will help you and if you want 20 records then make your query for 20 records also create pagination below
Here, you can have the Plug-in and Demo.