check if JSON data has changed and alert rows - javascript

I am trying to develope a app that checks MYSQL table every minute for new messages and if there is any it should alert the user and show the message. This is the code I use, how should I modify it to make it work?
setInterval ( "getMessages()", 60000 );
var oldmessage = "";
function getMessages() {
$.getJSON(serviceURL + 'messages.php?ID=' + ID, function(message) {
if(JSON.stringify(message) != JSON.stringify(oldmessage)){ // old message is not same as new
var messages = data.key[0];
alert(messages.NEW);
});
oldmessage = message;
}
So what I'm trying to do is save old message to variable and compare it after minute, and if it has changed I alert row NEW

The possible solution is, you take a new column in mysql to mark as viewed or not. By default that will be not viewed (say 0). In your PHP code you should retrieve one row which is marked as "Not viewed" or 0. And same you should display via AJAX and update back that row with 1 (viewed).
If you dont receive any rows, send nothing to AJAX and handle the messages accordingly no new rows found.
This is just a logic and hope it helps.

Related

Setting up a delay notification with php

I need to write a php function for sending a Telegram notification after 4 hours.
With the application i'm posting data into a SQL db, after I pressed the Submit button, i need that a php function starts and after 2 days sends to my Telegram channel a notification, with some of the data that i've posted into the db record.
For the posting part and Telegram part i'm ok, i've already linked the website to the channel and normal notifications from php work fine, but i need some advice on the "reminder" part.
I was thinking about some date() function and post the value in to the record, make another var with the date + 2days e make some for or while cycle but i don't think that this can works. Some advice?
I'm new to php, maybe i dont know some function that could help me?
Add to your table a column and name it notification_send and give it a default value of 0
Create a crontab that calls a php file for example:
*/60 * * * * php -f /etc/www/my_notification.php : calls the file every 60 mintues
In this file create a query that selects all the data with the notification_send = 0 then check if the current_date - date column of each row => 2 days :
If so : update the notification_send value to 1 and send your notification
As I commented, your approach is right. As you asked something more, though, I chose to write an answer.
As you asked, when you send a Telegram notification you have to send a reminder notification after 2 days (48h). If I'm right it's an e-mail.
First of all, as you said, you have to create a column to warn when the remember should be send.
Also, to know if the reminder has been sent or not you have to create another column. It could be a flag (true/false) or a datetime column (null = not sent, filled = sent).
Besides that, a cronjob or schedule have to call a PHP script. I'll show to you an example of a PHP script.
I'll call the table as reminder and the column sendIn and isSent.
//select only the reminder that has the sendIn lesser than now and that not has been sent
$statement = $pdo->query("SELECT * FROM reminder WHERE sendIn <= NOW() AND isSent is null");
//prepared statement to update the reminder sent
$updateStatement = $pdo->query("UPDATE reminder SET isSent = NOW() WHERE id = :id");
foreach($statement as $reminder)
{
/**
script to send the reminder
**/
//update the reminder
$updateStatement->execute(array(':id' , $reminder['id']));
}
To create a cronjob, you could take a look here:
https://askubuntu.com/questions/2368/how-do-i-set-up-a-cron-job
You don't need to delete the cron, just let it run periodically and send all your reminders.

Check whether the number of database rows changed compared to last time the PHP script is run?

I'm a bit stuck on how to program this: here's what I'm trying to do - I'm writing a simple chat application. There are two parts:
1.The send message part - where a message is typed into the textarea and stored into the database (I implemented this with jQuery AJAX)
**Database: There are two columns in the database, Date and Message
2.The receive message part - where new updates from the server are updated on the page without refreshing the page (I implemented this with HTML 5 SSE).
At a higher level, here's the main problem: I don't know how to write a condition - the condition being the code within the IF block running ONLY when the database has been updated compared to last time the even was fired - in other words, it should update when there is a new message only ONCE, instead of what you get below:
Here's the two code pages (I think it's better to include it all or else the context is a bit vague):
Quick summary:
chat.php - the main chat interface
messaging.php - the send button on the chat redirects here for handling
get_message.php - listens in on new messages and displays it in AJAX style
chat.php
<!-- display window -->
<div class = "message-window" id = "message-window">
Chat starts
</div>
<!-- listens in to new server updates and updates with new messages -->
<script>
if(typeof(EventSource) !== "undefined") {
var source = new EventSource("get_message.php");
source.onmessage = function(event) {
document.getElementById("message-window").innerHTML+=event.data + "<br>";
};
} else {
document.getElementById("message-window").innerHTML="Sorry, your browser does not support server-sent events...";
}
</script>
<!-- comopse message area -->
<div class = "send-wrapper">
<textarea id = "compose"></textarea>
<button type = "button" id = "send">Send</button>
</div>
<!-- event handler for click button to pass along data on the page -->
<script>
$(document).ready(function() {
$("#send").on('click', function() {
$.post(
// file
"messaging.php",
// data
{
// date: Date.toLocaleString(),
message: $("#compose").val()
},
// function after success
function(data, status) {
alert("Data: " + data + "\nStatus: " + status);
var singleMessageContent = $("#compose").val();
$("#message-window").html(
$("#message-window").html() + "<br />" + singleMessageContent
);
});
});
});
</script>
get_message.php
<?php
// get_message.php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
echo "retry: 1000\n";
// Create connection
$link = mysqli_connect('localhost', 'root', 'root', 'button');
// If number of rows changed from last retry
IF BLOCK (...)
// Get the most recent row
$query = "SELECT message FROM messages ORDER BY Date DESC LIMIT 1";
$result = mysqli_query($link, $query);
// echo the message field
$most_recent_row = mysqli_fetch_row($result);
echo "data: {$most_recent_row[0]}\n\n";
IF BLOCK (...)
flush();
?>
As you can see, what I'm stuck on is the if block - the event is fired every time by the EventSource object on chat.php (this is correct I presume?), so how do I compare the database in question AT DIFFERENT times the event was fired? I need this because I'd like to write this such that messages show ONLY when the database is updated.
if(current_database_rows != old_database_rows)
Here are my thoughts:
Something to do with a global variable? In terms of setting the global variable to count the number of rows in the database at the end of each execution of the php code, run mysqli_num_rows($result), and compare to this variable. My question is - how would you create this "shared" variable that doesn't lose its value in between firing events?
If you can fill me in on a possible condition, or an alternative solution, or other ideas, I'd appreciate it. Thanks!
If you're storing the date(hopefully time?) that a message is sent, you could return the time of the last chat message then keeping sending back that updated value to your query(through ajax) to only receive chat past that time.
Upon the ideas that were mentioned by the folks kind enough to answer, the simplest way is to keep an additional field in the database when a message is added as a record. This shows whether the message has already been retrieved or not. Once it has, it's set to true, bounced back to the jQuery in chat.php to handle, and voila, it's solved. :) Thanks guys!

Interactive for + get function

I need a problem with a function to update some informations in my database (I'm using the websql). In my application, I'm showing a loading box for do the update, but, the for ends before the get function is complete and the loading box e closed.
I need that the next interaction of the for only happen when the get is finish.
Someone has a solution for this? :(
I'm using the appframework intel (jqmobi)
for (var i=0; i<len; i++){
var url = "http://172.25.129.30:8180/prax/rest/ocorrenciaJSONBean/consultarStatusOcorrencia/"+results.rows.item(i).id;
$.get(url,function(data){
tx.executeSql('UPDATE ocorrencias SET status="'+data.responseText+'" WHERE id = '+results.rows.item(i).id);
});
};
I have the following scenario:
An internal bank with a list of calls that a user opened on cell. What I want is to upgrade the status of the bank.
Today I do a query on internal bank and each id I perform a get on a webservice place to know the status of the call. I would like the next interaction is only occurred when the GET was finalized.
The problem here is that once the function ends, the screen refreshes and the message is "loading" disappears. This is occurring earlier than expected, since the end is before all GETs are finalized.
The get is not waiting to perform a call so you need to do a callback in your get function to perform the next one. You could do something like this:
var index = -1;
function perform_get(){
index++;
var url = "http://172.25.129.30:8180/prax/rest/ocorrenciaJSONBean/consultarStatusOcorrencia/"+results.rows.item(index).id;
$.get(url,function(data){
tx.executeSql('UPDATE ocorrencias SET status="'+data.responseText+'" WHERE id = '+results.rows.item(index).id);
})
.done(perform_get);
}
Now it is waiting to perform the next get call.
Hope this helps.

creating new message notifications within <title></title> from a chat box

I'm trying to create notifications for my chat box, as seen beside the 'talk' title when ever some one new messages you. I've tried multiple things that never work.
a busy cat http://goawaymom.com/damit.png
here is my code
$(document).ready(function(){
//If user submits the form
$("#submitmsg").click(function(){
var clientmsg = $("#usermsg").val();
$.post("post.php", {text: clientmsg});
$("#usermsg").attr("value", "");
return false;
});
//Load the file containing the chat log
function loadLog(){
$.ajax({
url: "log.html",
cache: false,
success: function(html){
var chatbox= $("#chatbox");
var atBottom = (chatbox[0].scrollHeight - chatbox.scrollTop() == chatbox.outerHeight());
chatbox.html(html);
if (atBottom )
chatbox.animate({ scrollTop: 99999 }, 'normal');
}
});
}
setInterval (loadLog, 2500); //Reload file every 2.5 seconds
//If user wants to end session
$("#exit").click(function(){
var exit = confirm("Are you sure you want to end the session?");
if(exit==true){window.location = 'index.php?logout=true';}
});
});
does any body know how i would go about this. Everything I've tried so far has failed. I tried
using a set interval function that didn't work.
So, if I'm understanding correctly, submitting a message will append it to the end of log.html? I don't think that's going to work for what you're trying to do. You need to have a service to keep track of new posts so that you can check for updates, rather than just reloading the innerHTML of a div.
Once you have that in place, you can keep a count of how many new messages you've loaded since the chat had focus and reset it to 0 every time the chat gets focus.
You can update the title using document.title. So whenever you need to update the count, you can do
document.title = 'my normal title (' + newCount + ')';
Simply put, this isn't a problem you can solve with javascript, you need to redesign your app.
Your question is a bit incomplete / unclear. When you say "whenever someone new messages you", do you mean just when a new message appears (not necessary for you, but rather it's for the whole chat room).
Assuming that's the case, then the number is going to keep increasing whenever someone types something, which leads to the question: when do you decrement the number?
Here's a piece of code that will help you get started. It won't decrement the notification number, because in your question you didn't clarify when that number resets.
In $(document).ready add the following line in the end
// Load log and cache number of message on page when it first loaded
// Pass in a callback function to cache the message count.
loadLog(function(){
window.lastReadMessageCount = $('.msgln').length;
});
Update the loadLog to take in callback:
function loadLog(callback){
...
success: function(html){
if (callback) callback();
...
}
...
}
Now you know how many message the user has seen when the page loaded. Now whenever the page updates the chat, we want to update the new message count.
In your loadLog(), Add the following lines to the end
newMessagesCount = $('.msgln').length - lastReadMessageCount;
document.title = newMessagesCount > 0 ? 'title (' newMessagesCount ')' : 'title';
That's it! All you have to do now is clarify when you want lastReadMessageCount to be updated.

$.get() troubles before submitting page

Think a shopping basket with some "goods" in it.
I have a <li> list of elements and each of them has a field containing a number - the amount.
Conceptually this is what i want: When the user presses a button, i loop through each <li> element picking the amount. Then i do a $.Get() to call the server with the goods id + the amount to check if the store has enough of the particular item. The server replies either True og False.
This reply is temporary stored in a html field.
Now after the looping is done, i check if there were a False reply on any of the goods.
If so i highlight the "false" items. Or else i simply submit.
OK, the problem is that my code seams to continue past my $.get() call-back function, so the final check to see if any false was returned is evaluated before the $.get() actually receives a result from the server.
Anyway this is what i think is happening...
Now lets look at some code:
var tmp = new Array();
var id = '';
var c = '';
var n = 0;
var z=0;
$('#basket').find('li.list').each(function() {
c = $(this).find('input.fldamount').val(); // this is the amount field
id = $(this).attr('id'); // this is the id no of the item
$.get('./(RPC)?OpenAgent&cmd=movewhcheckamount&unid='+id+'&count='+c, function(data) {
$('#RPCResult').val(data); // i store the returned value in a html field
if ( $('#RPCResult').val() == "true" ) {
tmp.push( id+'|'+c ); // if true is returned, i push the id & amount to an array
} else {
$(this).addClass('red'); // else i tag the item
n=n+1; // and then increment a counter
}
} ); // $('#basket')
var t = window.setTimeout( function() {
if (tmp.length > 0 && n == 0) { // if i got items in the array AND my false counter is zero
$('#SelectedArtikler').val( tmp.join(";") ); // then i store the array as text in a field
document._FlyttArtikel.submit(); // and submit
} else if (n > 0) {
// show a popup
alert("You're trying to move more items than exists...");
} else {
alert("ops, nothing to move..."); // should never end up here...
}
}, 1000);
window.clearTimeout(t);
As you can see, i have tried to counter-act the code running past my call-back function with a setTimeout, so that i basically wait a sec to give the server time to respond.
I did have another loop around the setTimeout the continued as long as my #RPCResult field was empty, but that resulted in an infinite loop.
I have the #RPCResult field visible so i can see what happens and what i see is that the popup "You're trying to move more items..." is shown and RIGTH AFTER i press ok on that popup THEN the #RPCResult field gets the result true/false.
I now some of the code can be optimized but what i'm interested in right now is getting the $.get() result in a proper fashion.
Thanks in advance ;-)
You're going to have to place the code that's going to run when all the "$.get()" calls are finished inside the callback routine. That's the only place where you can be sure that you've actually gotten the server response(s). Keep a counter of how many calls have returned, and when the counter increments up to be equal to the total number of items, then you know that all of the responses are available.
Thus:
var basketSize = $('#basket').find('li.list').length, completed = 0;
gives you the number of items and initializes the counter. Inside the callback function passed to "$.get()" you can then do something like this:
if (++completed === basketSize) {
// code currently in the "setTimeout()" callback
}
Your code already appears to be doing some of this work (the "n" variable that you increment).
Now, that said, I'll also note that it's quite crazy to perform separate HTTP transactions for each of your "items". You should bundle them all up into one HTTP request that returns a list of answers.
Also, there's really no point at all in storing the response to the "$.get()" in that "RPCresult" field; just examine the value of "data", since nothing ever looks at "RPCresult" again anyway.

Categories

Resources