AJAX: download new content every X seconds using jQuery - javascript

I have page with posts. Initially posts was added by server-side code.
I need every 60 seconds download and show new posts from server.
Server can return 0 to N posts. Page returned by server have this format for two posts (most recent on top):
<div class='post' data-id='456'>...</div>
<div class='post' data-id='123'>...</div>
There is my code:
<html>
<head>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script>
var lastPostID;
$(document).ready(function(){
var j = jQuery.noConflict();
j(document).ready(function() {
setInterval(function(i) {
lastPostID = j(".post div:last").data("id");
console.log(lastPostID, "lastPostID");
j.ajax({
url: "/post/"+lastPostID,
cache: false,
success: function(html){
j("#temp").html(html);
j('#temp').prependTo("#posts");
j("#temp").empty();
}
})
}, 10000)
});
});
</script>
</head>
<body>
<div id="temp" style="display: none;"></div>
<div id="posts">
<div class='post' data-id='100'>...</div>
<div class='post' data-id='20'>...</div>
<div class='post' data-id='1'>...</div>
</div>
</body>
</html>
Can you please recommend me any good jQuery timer plugin?
I see at JS console every 10s:
null "lastPostID"
Where I have an error?
Update:
If I use:
<script>
var divs = document.getElementsByClassName('post');
console.log(divs.length, "divs with class *post*");
for(var i=0; i<divs.length; i++) {
var id = divs[i].getAttribute('data-id');
console.log(id, "lastPostID");
}
</script>
Output is OK:
3 "divs with class *post*" jQuery_div_update.html:37
100 lastPostID jQuery_div_update.html:40
20 lastPostID jQuery_div_update.html:40
1 lastPostID
But with jQuery:
<script>
$(document).ready(function(){
var lastPostID = $(".post div:last").data("id");
console.log(lastPostID, "lastPostID");
});
</script>
Output is bad:
null "lastPostID"
Why?

If you want to poll some external resource (with an AJAX call, for example) you can follow the "Recursive setTimeout pattern" (from https://developer.mozilla.org/en-US/docs/Web/API/Window.setInterval). Example:
(function loop(){
setTimeout(function(){
// logic here
// recurse
loop();
}, 1000);
})();

use setInterval() instead of setTimeout()
something like:
setInterval(function(){
$.ajax({
url: "test.html",
context: document.body
}).done(function() {
//do something
});
},1000*60);
http://www.w3schools.com/jsref/met_win_setinterval.asp
https://api.jquery.com/jQuery.ajax/

Related

Add the ability to render comments when the comment-list elements should be filled with text "Loading..." and show results one by one

I'm trying to render results one by one with some text like "Loading..." and show results one by one. I found answers at one, two and tried to solve this but it shows only one loading text and renders, shows all results at a time. The results should appear one after the other, with the order preserved. If any error occurs during the loading, the tag should be left empty. How to solve this challenge? For full question please refer here
HTML
<!DOCTYPE html>
<html>
<head>
<title>Render Comments</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
</head>
<body>
<div class="comment-list" data-count=1></div>
<script type="text/javascript" src="./app.js"></script>
</body>
</html>
JS
"use-strict";
var commentList = $(".comment-list");
var count = $(".comment-list").data("count");
var url = "https://jsonplaceholder.typicode.com/comments?postId=" + count;
$.ajax({
url: url,
method: "GET",
beforeSend: function () {
commentList.html("Loading...");
},
success: function (data) {
commentList.empty();
data.forEach(function (comment) {
commentList.append(`
<div class="comment-item">
<div class="comment-item__username">${comment.id}</div>
<div class="comment-item__message">${comment.name}</div>
</div>`);
});
},
error: function () {
// commentList.empty();
data.forEach(function () {
commentList.append(`
<div class="comment-item">
<div>Oops! Error occured to show the results</div>
</div>`);
});
},
});
You might consider doing this with CSS instead of with javascript. There are many examples including link. If you insist on doing this with javascript you need to break up the code adding the elements to the page using setInterval or setTimeout.

Handlebars duplicating ajax output on click

I'm using Handlebars to print out a list of books, where if you click on the title of a book you get a new div showing details. I'm able to print out the list and click on the book title to get details, but every title I click outputs the details from the first book that I clicked instead of the details for that book itself. I believe this has something to do with binding but haven't found a syntax that seems to work. Here's my HTML & Handlebars code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Library</title>
</head>
<body>
<div class="main"> <div id="book-list-items"></div></div>
<div id="book-details-items"></div>
<script src="js/jquery-1.11.1.min.js"></script>
<script src="js/handlebars-v1.3.0.js"></script>
<script src="js/main.js"></script>
<script id="book-list-template" type="text/x-handlebars-template">
<div class="book-list">
<h3 class='template title'>{{title}}</h3>
</div>
</script>
<script id="book-details-template" type="text/x-handlebars-template">
<div class="book-details">
<h3 class='template title'>{{title}}</h3>
<h4 class='template year'>{{year}}</h4>
<h4 class='template rating'>{{rating}}</h4>
</div>
</script>
</body>
</html>
And here's the JavaScript:
$(document).ready(function(){
var source = $('#book-list-template').html();
var source2 = $('#book-details-template').html();
var template = Handlebars.compile(source);
var template2 = Handlebars.compile(source2);
$.ajax({
type:'GET',
url: 'https://....',
data:{ api_key: '....'
}
}).done(
function(data){
populate_template(data)
});
var populate_template = function(data){
data.results.forEach(function(book){
var html = $(template(book));
$('.main').append(html);
html.click({book:book}, book_info)
})
}
var book_info = function(event){
id = event.data.book.id
$.ajax({
type:'GET',
url: 'https://....' + id,
data:{ api_key: '....'
}
}).done(function(data){
var html2 = template2(data);
$(document).trigger('change', event.currentTarget);
$(document).on('change', function(e, listing){
e.preventDefault();
$(listing).replaceWith(html2)
});
});
};
});
Can anyone tell me where I'm going wrong? I assume it's in the #book-details-template script but am stuck on what the syntax would be.
I suppose because the "change" listener on document stays active from the first call and in the followings call it's duplicated and so on...
Try to eliminate the listener and put the template into the book-details-items:
$("#book-details-items").html(html2);

Javascript not working when I change to Google JQuery Libraries?

Previously I am using JQuery library from here
http://jquery.com/download/
http://code.jquery.com/jquery-migrate-1.2.1.min.js
I try to include the following code, it work perfectly.
Javascript
$(document).ready(function(){
function loading_show(){
$('#loading').html("<img src='images/loading.gif'/>").fadeIn('fast');
}
function loading_hide(){
$('#loading').fadeOut('fast');
}
function loadData(page){
loading_show();
$.ajax
({
type: "POST",
url: "listcontact.php",
data: "page="+page,
success: function(msg)
{
$("#con").ajaxComplete(function(event, request, settings)
{
loading_hide();
$("#con").html(msg);
});
}
});
}
loadData(1); // For first time page load default results
$('#con .pagination li.active').live('click',function(){
var page = $(this).attr('p');
loadData(page);
});
$('#go_btn').live('click',function(){
var page = parseInt($('.goto').val());
var no_of_pages = parseInt($('.total').attr('a'));
if(page != 0 && page <= no_of_pages){
loadData(page);
}else{
alert('Enter a PAGE between 1 and '+no_of_pages);
$('.goto').val("").focus();
return false;
}
});
});
HTML
<div id="con">
<div class="data"></div>
<div class="pagination"></div>
</div>
And Then I try to use JQuery js from Google instead from JQuery.com
https://developers.google.com/speed/libraries/devguide#jquery
ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js
The Tab menu still can work, however I cannot get any data from listcontact.php
How can I make it work in Google JQuery?
this is all my script tag
<script src="jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<script type="text/javascript" src="ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
This is my tab menu
<nav>
<div id="tabs">
<ul>
<li><b>More Details</b></li>
<li><b>Contact</b></li>
<li><b>Files</b></li>
<li><b>Sales pipeLine</b></li>
<li><b>Call report</b></li>
</ul>
<div id="tabs-1">
<?php //include('viewdetail.php') ;?>
</div>
<div id="tabs-2">
<?php
if( $view == 0)
{
include('contact.php');
}
else
{
include('newcontact.php') ;
}
?>
</div>
<div id="tabs-3">
<?php //include('filemanagement.php') ;?>
</div>
<div id="tabs-4">
Under Development
</div>
<div id="tabs-5">
<?php //include('callReport.php') ;?>
</div>
</div>
</nav>
The code is inside my contact page, when I try to include it inside my tab
Are you developing locally? Or remotely?
If you are local....you usually have to attach http:// to the google apis
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
If not then just....
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
Should work...
This should also be replaced...from .live() to .on() as .live() is now deprecated
$('body').on('click','#go_btn', function(){
var page = parseInt($('.goto').val());
var no_of_pages = parseInt($('.total').attr('a'));
if(page != 0 && page <= no_of_pages){
loadData(page);
}else{
EDIT / UPDATE
You posted this...
<script src="jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<script type="text/javascript" src="ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
Change to this...
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
The jquery needs to be above the jquery-ui, as the ui has a dependancy on Jquery, and you can remove v1.9 no sense in loading jquery twice
EDIT 3
I would change this...you don't need that ajaxComplete call, since the success function is doing that anyway...
$.ajax
({
type: "POST",
url: "listcontact.php",
data: {page: page},
success: function(msg)
{
loading_hide();
$("#con").html(msg);
}
});
And you made sure to change both your live()'s???
You had two, the other one should look like this...
$('body').on('click','#con .pagination li.active' function(){
var page = $(this).attr('p');
loadData(page);
});
try to include the same version JQuery from google :
Number of version JQuery from google should be equal number of version JQuery from Jquery website
but if you want to use recent version, there are some changes , and you should modify something in your code, see log console for more info about problem and check documentation of JQuery here
Looks like live might not work with the latest version
Replace
.live('click'
with
.on('click'
If there are any dynamically added elements on the page replace your events with this syntax
$(staticContainer).on('click', 'selector' function(){
Where staticContainer is the closest static ancestor of the element.
selector is the element to which you want to attach the event.
I had experience with similar issue, it may deal with deprecated functions! check EACH piece of function, so that deprecated methods are corrected :) Hope this help you go to somewhere right :)
deprecated-ajax-or-jquery-command-cause-no-result-returned
Enjoy!

Debugging jquery or javascript using firebug

I wrote a code in jquery. I was not running initially, then i checked online jslint for syntax errors. I caught some errors. Now still the code was not working as expected. So i went for firebug. I haven't done a lot of debugging. I am new to it. Here is my code
var j = 2;
var friends = [];
var distance =[];
$(document).ready(function () {
$('#button').click(function () {
if (j < 11) {
$('#friends').append('Friend' + j + ':<input type="text" id="friend' + j + '"/><br/><br/>');
j++;
}
else {
alert("Limit reached");
}
});
$('button').click(function(){
console.log("button clicked");
var a =[];
for(i=1;i<=j;i++)
{
a[i] = $("#friend" + i).val();
}
var gurl = "http://maps.googleapis.com/maps/api/distancematrix/json?"+
"origins=" +
a.join('|').replace(/ /g,'+') +
"&destinations=" +
a.join('|').replace(/ /g,'+') +
"&sensor=false";
jQuery.ajax(
{
type: "GET",
url: gurl,
dataType: 'jsonp'
}).done(function (response)
{
var rows = response.rows;
alert("hello there");
for (var i = 0; i < rows.length; i++)
{
for(var j=0;j<elements.length;j++)
{
distance[i][j] = rows[i].elements[j].distance;
}
}
alert(distance[1][3]);
});
});
});
Now, what it should do is Go to this link and get the data from json file and store it inside the 2 dimensional array distance[][]. Finally after storing all the data, it should display the result of "distance[1][2]" as an alert.
Now i dont know whats wrong in this code and how to find the logical errors using firebug. What should make my work easy ?
ps: heres the HTML file
<!doctype html>
<html>
<head>
<title>TakeMeHome</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript" src="js/app.js"></script>
<script type="text/javascript" src="js/jquery-1.9.0.js"></script>
<script type="text/javascript" src="js/jquery-ui-1.10.0.custom.js"></script>
<script type="text/javascript" src="js/jquery-ui-1.10.0.custom.min.js"></script>
</head>
<body>
<center>
<form id="locations">
Your Place:<input id="source" type="text"><br/>
<br/>
<div id="friends">
Friend1:<input id="friend1" type="text"><br/>
<br/>
</div>
<div id="button">
Add!</div>
<br/>
<br/>
<button>GO!</button>
<br/><br/>
<div id="map" style = "width: 500px; height: 500px"><br/>
</form>
</center>
</body>
</html>
Hey here is a working fiddle with your code, and some examples of ways to debug your js :
http://jsfiddle.net/QxP7p/3/
As you see you can do nice stuff like :
console.log("distance : ");
console.log(distance);
Hope it helps
They were a few mistakes as well, couldn't help fixing them
The easiest way to debug is to use firebug and console.log() variables or messages at certain points in your script, so that you can better understand what is going on at various steps of your script. You can see the output in the Console tab of firebug.
You can also add breakpoints and watches from some of the other tabs. For example in the DOM tab you can rightclick on a variable and add a watch, or from the Script tab you can click on a position in your script to set a breakpoint or watch, and it will stop the script at that point and/or show a dump of vars at that point.

setInterval with jQuery.html only updates once?

<?php
echo '
<script type="text/javascript">
$(function() {
var refresh = setInterval(function() {
$("#content").html("'.rand().'");
}, 3000);
});
</script>
<div id="content"></div>
';
?>
This will update the div "content" with a random number after 3 seconds, however it only updates once. Why does it not continually generate a new number every three seconds, and how can I make it do precisely that?
Thank you in advance for any assistance rendered.
Ha. PHP is run on the SERVER side. JS is on the client.
you need to generate the rand on the JS side not he php side...
js code:
<script type="text/javascript">
$(function() {
var refresh = setInterval(function() {
var randomnumber = Math.floor(Math.random()*11);
//where 11 dictates that the random number will fall between 0-10
$("#content").html(randomnumber);
}, 3000);
});
</script>
<div id="content"></div>

Categories

Resources