I'm trying to implement simple Comet chat example and for this I implemented Long polling which calls itself recursively every 30 seconds.
When pressing on button I want another ajax request to send new data on Server using POST.
For now I just put alert to this function to trigger click event
<script src="http://code.jquery.com/jquery-1.6.2.min.js"></script>
<script type="text/javascript">
var polling = function poll(){
$("#postMessage").click(function () {
alert("request");
});
$.ajax({ dataType: 'json',url: "CometServlet", success: function(data){
if (data !=null){
$('#message').append(data.sender+" : " + data.message+"<br />");
}
}, complete: poll, timeout: 30000 });
}
$(document).ready(polling)
</script>
And my HTML is like this:
<div>
<input type="button" id="postMessage" value="post Message">
</div>
<div id ="message" name="message"></div>
When I click on button my alert is shown several times. Why? How can I solve it?
As Dave mentions, that's not what the timeout option is for. Try something using setTimeout instead. Also, you're mixing your polling logic and your click handler (I think). Here's how you would separate them:
function poll() {
$.ajax({
dataType: 'json',
url: "CometServlet",
success: function(data){
if (data !=null){
$('#message').append(data.sender+" : " + data.message+"<br />");
}
},
complete: function () {
setTimeout(poll, 30000);
}
});
}
$(document).ready(function () {
$("#postMessage").click(function () {
alert("request");
});
poll();
});
Example: http://jsfiddle.net/VyGTh/
In your code after every Ajax call you re-bind click event to #postMessage and that's why you had couple of alert messages. You need to bind click only once in page load. You can fix it by doing something like:
<script src="http://code.jquery.com/jquery-1.6.2.min.js"></script>
<script type="text/javascript">
var polling = function poll(){
$.ajax({ dataType: 'json',url: "CometServlet",
success: function(data){
if (data !=null){
$('#message').append(data.sender+" : " + data.message+"<br />");
}
},
complete: poll,
timeout: 30000
});
}
$(document).ready(function(){
// Now Click only binds one time
$("#postMessage").click(function () {
alert("request");
});
polling();
});
</script>
Related
I have been trying to create a chatting system using php+ ajax + mysql.
<?php
session_start();
?>
<html>
<head>
<title>Live Table Data Edit</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" />
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
</head>
<body>
<div class="container">
<br />
<br />
<br />
<div class="table-responsive">
<h3 align="center">You Are : <?php echo $_SESSION['name'];
?></h3><br />
<div id="live_data"></div>
</div>
<div id="messages"></div>
<div class="area" style="display:none">
<textarea id="text" name="text"></textarea>
<input type="submit" id="sub" name="sub" value="Send" />
</div>
</div>
</body>
</html>
<script>
$(document).ready(function() {
function fetch_data() {
$.ajax({
url: "select.php",
method: "POST",
success: function(data) {
$('#live_data').html(data);
}
});
}
fetch_data();
$(document).on('click', '.first_name', function() {
var id = $(this).data("id1");
function fetch_chat() {
$.ajax({
url: "fetch_chat.php",
method: "POST",
data: {
id: id
},
dataType: "text",
success: function(data) {
$('#messages').html(data);
$("div.area").show();
}
});
}
function myTimeoutFunction() {
fetch_chat();
}
myTimeoutFunction();
setInterval(myTimeoutFunction, 1000);
fetch_chat();
$("#sub").click(function() {
var text = $("#text").val();
$.post('insert_chat.php', {
id: id,
msg: text
}, function(data) {
$("#messages").append(data);
$("#text").val('');
});
alert(text);
});
});
});
</script>
but the problem with this code is that it worked only for the first user I chat with but the screen starting blinking frequently when I click on other users' name. for example: user 'a' is logged in and click on user 'b' and starts the chat. everything works fine till now, but when user 'a' thinks to chat with a another user 'c' the whole chat part start blinking with all chats stored in database. plz tell me where I m goin wrong.
This needs a complete rethink really, to be rid of all the potential bugs.
The problem you describe above is because you're creating a new timed interval every time someone clicks on a name, so gradually this builds up and you are requesting every few milliseconds instead of every second. This is unsustainable. There's no need really to be declaring intervals, functions etc etc within the "click" handler of the name. I think you're doing this because of the dependency on the user ID which results from selecting a name. However you can overcome that by assigning the value to a global variable.
Doing this means you can move all the functions outside the click handler, removing any danger of re-creating the same intervals / events multiple times. I've also changed it so it doesn't use an interval. Instead, fetch_chat calls itself again 2 seconds after the previous response is received. That way, if a fetch takes longer than normal, you don't have multiple competing fetch operations running in parallel and causing potential confusion. I also increased the time interval to something which is still reasonable, but won't overload the server.
Here's a complete rework of your code:
<script>
var currentID = null;
var chatTimer = null;
function fetch_data() {
$.ajax({
url: "select.php",
method: "POST",
success: function(data) {
$('#live_data').html(data);
fetch_chat();
}
});
}
function fetch_chat() {
$.ajax({
url: "fetch_chat.php",
method: "POST",
data: {
id: currentID
},
dataType: "text",
success: function(data) {
$('#messages').html(data);
$("div.area").show();
chatTimer = setTimeout(fetch_chat, 2000); //request the chat again in 2 seconds time
}
});
}
$(document).ready(function() {
$(document).on('click', '.first_name', function() {
currentID = $(this).data("id1");
//immediately fetch chat for the new ID, and clear any waiting fetch timer that might be pending
clearTimeout(chatTimer);
fetch_chat();
});
$("#sub").click(function() {
var text = $("#text").val();
$.post('insert_chat.php', {
id: currentID,
msg: text
}, function(data) {
$("#messages").append(data);
$("#text").val('');
});
alert(text);
});
fetch_data(); //this will also trigger the first fetch_chat once it completes
});
</script>
P.S. If you want anything faster than 2 seconds refresh, then really you probably need to consider re-architecting the solution using websockets to get full 2-way communication, so the server can "push" chat items to the client instead of the client having to poll the server.
You are using setInterval, this is wrong, this will start a loop every time you click on a chat, you should have a single loop running over all your chats. Also consider using setTimeout instead of setInterval to ensure you get the response first.
I'm using an Ajax for partial loading my website. Content of GET data has images but these images appear after few seconds on page. Image size is about 20kB, so this is not a bottleneck.
I'm using php page which returns some content. This page loads in a while with images immediately but with ajax it loads text, but images after few seconds. How can I achieve quick load?
I'm using this function:
function loadMainEvents(resultDiv, cat, limit){
var spinner = new Spinner().spin(mainPageEvents);
$.ajax({
url: "/getMainPageEvents.php?category=" + cat + "&limit=" + limit,
type: "GET",
success: function(data){
resultDiv.innerHTML = data;
spinner.stop();
}
});
};
EDIT:
I created a test.php which is doing same thing
<html>
<head>
<script src='https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js' type="text/javascript"></script>
</head>
<body>
<div id="div" style="float:left;">wait</div>
<div id="div2">wait</div>
<script>
$(function () {
$.ajax({
url: "/getMainPageEvents.php?category=&limit=10&from=29.11.2015&to=29.11.2015&pno=1",
type: "GET",
success: function (data) {
$("#div").html(data).on('load', function () {
$(this).fadeIn(250);
});
}
});
$.ajax({
url: "/getMainPageEvents.php?category=&limit=10&from=29.11.2015&to=29.11.2015&pno=1",
type: "GET",
success: function (data) {
$("#div2").html(data).on('load', function () {
$(this).fadeIn(250);
});
}
});
});
</script>
</body>
getMainPageEvents.php returns only web content.
Network from developer tools:
You may want to try something like this in the success function. Hide the result div first and foremost, then after the data is loaded, show the div.
$(resultDiv).html(data).promise().done(function(){
spinner.stop();
$(this).fadeIn(250);
});
Possible second solution
$(resultDiv).html(data).on('load', function(){
spinner.stop();
$(this).fadeIn(250);
});
I'm trying to use setInterval to execute the php script update.php every 10 seconds and refresh div id = verification. For some reason setInterval is preventing the script from functioning. Any suggestions on where to place\change setInterval would be appreciate as I'm stumped (sorry entry level javascript user here). For clarity I omitted all the non-relevant details, such as vars.
<div id="verification"></div>
<script id="verification" language="javascript" type="text/javascript">
$(function() {
$.ajax({
url: 'update.php', //php
data: "", //the data "caller=name1&&callee=name2"
dataType: 'json', //data format
success: function(data) //on receive of reply
{
var foobar = data[2]; //foobar
$('#verification').html("(<b>" + foobar + "</b>)"); //output to html
}
});
});
setInterval(10000); //every 5 secs
</script>
Suggestions/Steps/Bugs:
Create a separate function to perform ajax request
Call this function on page load to run it when page is loaded
Use setInterval() to call the function every n seconds
id should always be unique. You're now using verification as if for <div> and <script>
You can remove id and language attributes of <script>. Those are not required.
Code:
function update() {
$.ajax({
url: 'update.php', //php
data: "", //the data "caller=name1&&callee=name2"
dataType: 'json', //data format
success: function (data) {
//on receive of reply
var foobar = data[2]; //foobar
$('#verification').html("(<b>" + foobar + "</b>)"); //output to html
}
});
}
$(document).ready(update); // Call on page load
// ^^^^^^
setInterval(update, 10000); //every 10 secs
// ^^^^^^
setInterval() takes a function (that it should execute) as it's first argument.
Try this:
setInterval(function(){
$.ajax({
url: 'update.php', //php
data: "", //the data "caller=name1&&callee=name2"
dataType: 'json', //data format
success: function(data) //on receive of reply
{
var foobar = data[2]; //foobar
$('#verification').html("(<b>"+foobar+"</b>)"); //output to html
}
});
}, 10000);
you are using setInterval in a wrong way - you can read about it here:
http://www.w3schools.com/js/js_timing.asp
Also please notice that AJAX calls are asynchronous - when program is going forward it doesn't mean that previous AJAX call has ended. You can "wait" for AJAX completition using some jQuery mechanisms like binding ajaxComplete or using when
You are missing the function block:
setInterval(function() {
// to do
}, 5000);
My suggestion is to go for setTimeout as you are running ajax it is not certain that it would complete within 5 seconds. In case if you wana go for it:
var dispatchUpdates = function() {
setTimeout(pullUpdates, 5000);
};
var pullUpdates = function() {
$.ajax({
url: 'update.php',
data: "",
dataType: 'json',
success: function(data) {
var foobar = data[2];
$('#verification').html("(<b>" + foobar + "</b>)");
dispatchUpdates(); // next updates
},
error: function() {
dispatchUpdates(); // retry
}
});
};
$(dispatchUpdates); //page load
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
I have the script below that works great but want to modify it for a desired effect. Right now it only works on initial page load. But how can I edit it to make it auto-feed every 30 seconds or so?
$.ajax({
type: "GET",
url: "Administration/data/people.xml"
}).done(function (xml) {
$(xml).find('fullName').each(function() {
var fullName = $(this).text();
$('<button type="button" class="mybutton" name="users" onclick="showUser(this.value)"></button>').attr('value', fullName).html(fullName).appendTo('#loadMe');
});
}).fail(function (response, error) {
$('#info').text('Error!');
});
EDIT: 1/24/14 3:55 AM
I added the interval function, but now it is on an infinite loop and is not overwriting, but instead adding over and over again.
$(document).ready(function(){
setInterval(updateMe,1000);
function updateMe(){
$.ajax({
type: "GET",
url: "Administration/data/people.xml"
}).done(function (xml) {
$(xml).find('fullName').each(function() {
var fullName = $(this).text();
$('<button type="button" class="mybutton" name="users" onclick="showUser(this.value)"></button>').attr('value', fullName).html(fullName).appendTo('#loadMe');
});
}).fail(function (response, error) {
$('#info').text('Error!');
});
}
});
Use the setInterval function to call the function every 30000 miliseconds.
have a look at javascript setInterval ()
Plenty of examples on the web but the basic syntax is
var intervalID = window.setInterval(code, delay);
I have the following jQuery Ajax call:
$.ajax({
type: "POST",
url: "addtobasket.php",
data: "sid=<?= $sid ?>&itemid=" + itemid + "&boxsize=" + boxsize + "&ext=" + extraval,
success: function(msg){
$.post("preorderbasket.php", { sid: "<?= $sid ?>", type: "pre" },
function(data){
$('.preorder').empty();
$('.preorder').append(data);
});
}
});
I want to display an image when the ajax call is in progress. How can I do that?
Thanks,
try this :
<script type="text/javascript">
$(document).ready(function()
{
$('#loading')
.hide()
.ajaxStart(function() {
$(this).show();
})
.ajaxStop(function() {
$(this).hide();
});
});
</script>
<div id="loading">
Loading....
</div>
This will show the loading image each time you are doing an ajax request, I have implented this div at the top of my pages, so it does not obstruct with the page, but you can always see when an ajax call is going on.
Something along these lines (showLoadingImage and hideLoadingImage are up to you):
// show the loading image before calling ajax.
showLoadingImage();
$.ajax({
// url, type, etc. go here
success: function() {
// handle success. this only fires if the call was successful.
},
error: function() {
// handle error. this only fires if the call was unsuccessful.
},
complete: function() {
// no matter the result, complete will fire, so it's a good place
// to do the non-conditional stuff, like hiding a loading image.
hideLoadingImage();
}
});
You can display the image just before this call to $.ajax() and then hide/remove the image in the post handler function (just before your .empty()/.append(data) calls.
It works. I have tested it.
<script type='text/javascript'>
$(document).ready(function(){
$("#but_search").click(function(){
var search = $('#search').val();
$.ajax({
url: 'fetch_deta.php',
type: 'post',
data: {search:search},
beforeSend: function(){
// Show image container
$("#loader").show();
},
success: function(response){
$('.response').empty();
$('.response').append(response);
},
complete:function(data){
// Hide image container
$("#loader").hide();
}
});
});
});
</script>
<input type='text' id='search'>
<input type='button' id='but_search' value='Search'><br/>
<!-- Image loader -->
<div id='loader' style='display: none;'>
<img src='reload.gif' width='32px' height='32px'>
</div>
<!-- Image loader -->
<div class='response'></div>