I've recently started learning jQuery and I'm trying to make a little messaging system, I've gotten the messages to update every 2 seconds. However, I don't want the messages to update if there aren't any new messages. This is my current message updating code.
$(document).ready(function () {
setInterval(function() {
$.get("get_messages.php", function (result) {
if ($('.messages').html() != result){
$('.messages').html(result);
}
});
}, 2000);
});
The if statement doesn't seem to be working even though the div and result should be the same.
I hope that you have timestamp or messageID on server that could tell your script if there are new messages after last check.
ex.
var lastMessageID = 0;
function checkMessages(){
$.ajax(url,{
data:{
last_message_id:lastMessageID
},
success:function(data){
// Count new messages
if (Object.keys(data).length > 0){
$.each(data,function(index, item){
$('.messages').prepend("<span class='message'>"+item.message+"</span>");
});
// We suggest that this is our last message
lastMessageId = data[Object.keys(data).length-1].id;
}
}
});
}
var intervalM = setInterval(function(){
checkMessages();
},2000);
And please save some trees by using gziped JSON data. :)
Related
I am making chat for my student group, and I am using AJAX to get my messages like this
//Initial call i make so user do not wait 2 seconds for messages to show
function marko() {
$("#porukice").load("messages.php"); //Load the content into the div
}
marko();
//autorefresh every 2 seconds
var auto_refresh = setInterval(
(function () {
$("#porukice").load("messages.php"); //Load the content into the div
}), 2000);
To send messages I am also using ajax, like this
var frm = $('#form1');
frm.submit(function (ev) {
$.ajax({
type: frm.attr('method'),
url: frm.attr('action'),
data: frm.serialize(),
success: function (data) {
document.getElementById("message").value = "";
document.getElementById('play').play();
}
});
ev.preventDefault();
});
This is part of message.php (where messages are generated)
$sql = $conn->query('(SELECT * FROM chat ORDER BY time desc limit 0, 10) ORDER BY time');
while($row = mysqli_fetch_array($sql))
{
$rows[] = $row;
}
foreach($rows as $row){
$time = date('H:i:s', strtotime($row['2']));
echo '['.$time.'] <b>'.$row['0'].'</b>: '.stripslashes($row['1'])."<br/>";
}
I am trying to play a sound when new message arrives>
only solution I came up with is to play a sound when message is sent with
document.getElementById('play').play();
as you can see in above code. I have no clue how to play it when messages are coming, when mysql row is updated.
I saw other answers on stackoverflow but they are not helping me.
NOTICE: $row['1'] is message, $row['0'] is user name and $row['2'] is time.
You could pass, from the PHP script that gets the messages, the value of the last id you got. Then, store it in a jQuery variable, and after you reload the messages, check if the ids are different, if they are (that means a new message came up), play the sound.
For example, after the foreach loop:
return json_encode(array('last_time' => $rows[count($rows)-1][2]));
On your jQuery:
var last_time = 0; // <--- New
var new_time = 0; // <--- New
// Initial call i make so user do not wait 2 seconds for messages to show
function marko() {
$("#porukice").load("messages.php"); //Load the content into the div
// New
if (last_time < new_time) {
document.getElementById('play').play();
last_time = new_time;
}
}
marko();
//autorefresh every 2 seconds
setInterval(function () { // <--- Some edits here
marko(); // <--- Some edits here
}, 2000);
// ....
var frm = $('#form1');
frm.submit(function (ev) {
$.ajax({
type: frm.attr('method'),
url: frm.attr('action'),
data: frm.serialize(),
success: function (data) {
document.getElementById("message").value = "";
last_time = new_time; // <--- New
new_time = data.last_time; // <--- New
}
});
ev.preventDefault();
});
I've not tested this, but you're free to do it and let me know.
EDITED to use time instead of id
I fixed this problem by creating separate file called sound.php
Sound.php is answering to get request with json response including date and time of last message
{"last_time":"2017-02-25 17:45:55"}
Then I am calling this file every 2 seconds with ajax, and if last_time has changed i play a sound
var skipped_once = false;
var old_time = 0
var auto_refresh = setInterval(function() {
$.get("sound.php", function(data) {
// if old_time different than last_time play sound
if (old_time != data.last_time) {
//do not play sound on first page load
if (skipped_once) {
document.getElementById('play').play();
out.scrollTop = out.scrollHeight - out.clientHeight;
}
skipped_once = true;
old_time = data.last_time;
}
});
}, 2000);
I have PHP site with MySql data base
I just added automatic save for a text area
and one of the users received the following error:
Too many connections in ...Unable to connect to database
maybe I have to change my ajax auto save:
bkLib.onDomLoaded(function(){
var myEditor = new nicEditor({iconsPath : 'include/nicEdit/nicEditorIcons.gif'}).panelInstance('area1');
auto_save_func(myEditor);
});
function auto_save_func(myEditor)
{
draft_content=myEditor.instanceById('area1').getContent();
int_id='<?=$_GET[interview_id]?>';
$.post("ajax_for_auto_save_interview.php", { interview_id: int_id,content:draft_content},
function(data){ });
setTimeout( function() { auto_sav_func(myEditor); }, 100);
}
in the page "ajax_for_auto_save_interview.php" I`m including the connection to the DB.
First thing is you should close your mysql connection every time you open it after your usage.
You can have a javascript variable to check whether an AJAX call is already issued and is it finished or not. Only if it is finished, you can re-issue new call
Like this:
var isAjaxStarted = 0;
bkLib.onDomLoaded(function(){
var myEditor = new nicEditor({iconsPath : 'include/nicEdit/nicEditorIcons.gif'}).panelInstance('area1');
if(isAjaxStarted == 0)
auto_save_func(myEditor);
});
function auto_save_func(myEditor)
{
isAjaxStarted = 1;
draft_content=myEditor.instanceById('area1').getContent();
int_id='<?=$_GET[interview_id]?>';
$.post("ajax_for_auto_save_interview.php", { interview_id: int_id,content:draft_content},
function(data){ isAjaxStarted = 0; });
setTimeout( function() { auto_sav_func(myEditor); }, 100);
}
maybe I am writing late you help in place it? thank you very much
<script type="text/javascript">
bkLib.onDomLoaded(function() {
var myNicEditor = new nicEditor({buttonList : ['bold','italic','underline','strikethrough','left','center','right','justify',/*'ol','ul',*/'forecolor',/*'fontSize','fontFamily',*//*'fontFormat',*//*'indent','outdent',*/'image','upload','link','unlink'/*,'bgcolor'*/,'hr','removeformat', 'youTube'/*,'subscript','superscript'*/],/*fullPanel : true,*/
iconsPath : '<? echo "".$IndirizzoPagina."".$IndirizzoCartella."";?>default/image/EditorDiTesto/nicEditorIcons.gif'});
myNicEditor.setPanel('myNicPanel'); //PANNELLO DI CONTROLLO
myNicEditor.addInstance('titolo'); //TITOLO
myNicEditor.addInstance('contenuto'); //CONTENUTO
});
<textarea name='contenuto' id='contenuto' class='box2'>".$ContenutoNotizia."</textarea>"
i used this code http://nicedit.com/
I have a jQuery function that loads a PHP file (which gets a JSON response from an application) every 100ms. What I am trying to do is have two different counters, one which will increment every time a request is sent and another counter which will increment as soon as it gets a JSON response. At the moment I have the following which is not working, they are both just counting the number of requests being sent:-
JQUERY
$(function() {
var MAXNUM = 9;
var count = 0;
var countSuccess = 0;
function newAsyncRequest() {
setTimeout(function() {
newAsyncRequest();
count++;
$(".request").html(count);
$.get('test.php', function(data) {
countSuccess++;
$( ".log" ).html(countSuccess);
});
}, 100);
}
newAsyncRequest();
});
PHP
require_once('scripts/php/controllers/curl.controller.php');
$postcode = 'LE11 5';
$postcode = rawurlencode($postcode);
$uri = 'http://192.168.1.110:8290/?pc='.$postcode; // Home
$response = CurlController::request($uri);
So my question is basically, how can I count the number of successful responses I am getting from .$get command?
Need to print count to .request, you were using countSuccess in both the statements
$(function() {
var MAXNUM = 9;
var count = 0;
var countSuccess = 0;
function newAsyncRequest() {
setTimeout(function() {
newAsyncRequest();
count++;
$(".request").html(count);
//need to print here
$.get('test.php', function(data) {
countSuccess++;
$( ".log" ).html(countSuccess);
});
}, 100);
}
newAsyncRequest();
});
You can use $.ajax's success parameter. The function passed to this parameter will only run if an ajax request is successful.
$.ajax({
url:"",
type: "get",
beforeSend: function(){ requestCounter++ },
success: function(){ successCounter++ }
});
What are you defijning as a success?
The .get 'success' is that the server responded which it hopefully always will do.
If you are definign success as somthign working in the PHP script then in the PHP then in the jquery success function check what was returned in 'data' to see if it was succesful.
I generally return a Json encoded array with an element called 'result' that is either set to ture or false by the PHP and the jquery can simple act on that record.
If NewMessage changes, I want an alert. I have tried live and change on and bind change, but nothing works.
Relevant PHP:
$message=6;
$myReturnData["Message"] = $message;
//JSON-encode and return
print json_encode($myReturnData);
Relevant jQuery:
setInterval(function(){
$.getJSON("foo.php", function(data){
var NewMessage=(data.Message);
if(NewMessage>0){
document.title= NewMessage + ' pm';}
$(NewMessage).live("change", function() {
alert(NewMessage);
});
});
}, 3000);
'change' is not doing what you think it should be. You should store the original message in a variable, then compare it to the new message you're getting. Like this:
var currentMessage = '';
setInterval(function(){
$.getJSON("foo.php", function(data){
var NewMessage=(data.Message);
if(NewMessage>0){
document.title= NewMessage + ' pm';
if (currentMessage !== NewMessage) {
alert(NewMessage);
currentMessage = NewMessage;
}
}
});
}, 3000);
Assuming you want function X to run when a variable controlled by the server changes. To that means you are using a polling mechanism.
So if you want your code to know when it receives a different message, you must store the previous message somewhere outside the scope of your callback function.
Most easy way:
var lastMessage = 'the server will never ever forever ever return this message';
setInterval(function(){
$.getJSON("foo.php", function(data){
// .. arbitrary code
if (lastMessage != data.Message)
{
alert('it changed');
lastMessage = data.Message;
}
// .. more arbitrary code
});
}, 3000);
i don't think the following code makes any sense or would even remotely work, because the NewMessage is not a DOM element, is it?
$(NewMessage).live("change", function() {
alert(NewMessage);
});
A button click fires my function that fetches image data via an AJAX-call:
$("#toggle_album").click(function () {
album_id = $("#album_id").val();
$.post('backend/load_album_thumbnails.php', {
id: album_id
}, function(xml) {
var status = $(xml).find("status").text();
var timestamp = $(xml).find("time").text();
$("#album_thumbs_data_"+album_id+"").empty();
if (status == 1) {
var temp = '';
var output = '';
$(xml).find("image").each(function(){
var url = $(this).find("url").text();
temp = "<DIV ID=\"thumbnail_image\">[img-tag with class="faded" goes here]</DIV>";
output += temp;
});
$("#album_thumbs_data_"+album_id+"").append(output);
} else {
var reason = $(xml).find("reason").text();
var output = "<DIV CLASS=\"bread\">"+reason+"</DIV>";
$("#album_thumbs_data_"+album_id+"").append(output);
}
$("#album_thumbs_"+album_id+"").toggle();
});
});
The data is returned in XML format, and it parses well, appending the data to an empty container and showing it;
My problem is that my image overlay script:
$("img.faded").hover(
function() {
$(this).animate({"opacity": "1"}, "fast");
},
function() {
$(this).animate({"opacity": ".5"}, "fast");
});
... stops working on the image data that I fetch via the AJAX-call. It works well on all other images already loaded by "normal" means. Does the script need to be adjusted in some way to work on data added later?
I hope my question is clear enough.
Okay, apparantly I hadn't googled it enough. Surfing my own question here on stackoverflow pointed me to other questions, which pointed me to the JQuery live() function: live().
However, it does not work on hover(), so I rewrote the script to use mouseover() and mouseout() instead:
$("img.faded").live("mouseover",function() {
$(this).animate({"opacity": "1"}, "fast");
});
$("img.faded").live("mouseout", function() {
$(this).animate({"opacity": "0.5"}, "fast");
});
... and now it works flawlessly even on the content I fetch from the AJAX-call.
Sorry if anyone has started writing an answer already.
You have to bind the new events each time you add a DOM element to the page.
There is a built-in function in jquery called live that does that for you.
I noticed you add the images from your xml; you can add there the new binds too.
$(xml).find("image").each(function(){
//this actually creates a jquery element that you can work with
$('my-img-code-from-xml-goes-here').hover(
function() {
$(this).animate({"opacity": "1"}, "fast");
},
function() {
$(this).animate({"opacity": ".5"}, "fast");
}
//i did all my dirty stuff with it, let's add it where it belongs!
).appendTo($('some-already-created-element'));
});
EDIT: corrected a wrong sentence.