I am new to js and jquery. The page I’m working on is a message board. First the page displays 10 most recent messages and then my jquery function is used to update the board automatically, pulling new data every 2 seconds. The most recent messages are displayed on the top. The older messages should be removed from the page.
Please note that this is a simplified version of the page. I’m trying to work out the logic before implementing it to the actual page. Hence instead of the message, the id is showed etc.
<?php
include ("../../db.php");
?>
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="../jquery/jquery.js"></script>
</head>
<body>
<script>
function update() {
$("#notice_div").html('Loading..');
$.ajax({
type: 'GET',
url: '2include.php?lastid='+ latestid + '',
timeout: 2000,
success: function(data) {
$("#cont_div").html(data);
$("#cont_div").clone().prependTo($("#newdiv")); // adding the pulled data to newdiv
$("#notice_div").html('');
window.setTimeout(update, 2000);
// animate
$("#newdiv").slideDown(1000,function(){ });
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
$("#notice_div").html('Timeout contacting server..');
window.setTimeout(update, 60000);
}
});
}
$(document).ready(function() {
update();
});
</script>
<div id="cont_div"></div>
<div id="newdiv"></div>
<?
$count = 1; // first message is the newest
$get = $DB->query("SELECT * FROM board ORDER BY id DESC LIMIT 10", __FILE__, __LINE__);
while ($msg = $DB->fetch_array($get))
{
echo "<div id='msgid' style='background-color:yellow'>".$msg['id']."</div>";
if($count == 1){
$latestid = $msg['id']; // newest message - passing to js
}
$count++;
} ?>
<script>
var latestid = <?=$latestid?>;
</script>
</body>
</html>
2include.php –
<?
include ("../../db.php");
$la = $_GET['lastid'];
$count = 1; // first message is the newest on load
$get = $DB->query("SELECT * FROM board WHERE id>'$la' ORDER BY id DESC LIMIT 5", __FILE__, __LINE__);
while ($msg = $DB->fetch_array($get))
{
echo "<div id='msgid' style='background-color:red'>".$msg['id']."";
if($count == 1){
$latestid = $msg['id']; // newest message
}
$count++;
?>
<script>
var latestid = <?=$latestid?>; // after pulling the newest message we overwrite latestid with the newest msg id
</script>
<? } ?>
result after inserting 3 new rows to the table after the first page load:
https://i.stack.imgur.com/rPf8N.jpg (sorry can’t post images yet)
the top red one is cont_div and appears every time new data is pulled for 2 seconds.
- What do you think of my code? I’m pretty new to jquery and not that good with javascript. This bit of code has taken me over 7 hours to build.
- Animation is not working (new messages should appear with the slide down animation.
- cont_div is displayed on the page (top red one on the image). Tried to put the content in variables or make the div invisible – nothing worked. If I made it invisible, the style would be copied to the new_div and it would be invisible there too.
- Only 10 messages should be displayed on one page. I haven’t figured out how to remove the older messages from the page.
I’ll treat things like a call center and answer your questions in the order they were received:
What do you think of my code?
Overall, your Javascript code is very clean and well-organized. I usually put my Javascript code in external files instead of directly in the HTML, but that’s about all I have to suggest for the Javascript. One little thing I found is that you don’t have to specify a callback if you don’t want one. This is perfectly valid JQuery:
$("#newdiv").slideDown(1000);Your PHP code is a little less organized, but you did say that you trimmed it down to post here, so I won’t comment on the formatting specifics. One thing I did notice, however, is that you have a security risk in this line:
$la = $_GET['lastid'];What if
lastidwas set to1'; DROP TABLE board;--? To guard against this, never use user input directly in a query. Since this value is an ID, you could say$la = intval($_GET['lastid']);, which will force the value to be an integer (strings will become 0). If you want to sanitize a string, check out mysql_real_escape_string.Animation is not working
In HTML,
ids are supposed to be unique. You should use aclassif you want multiple elements to have the same value. In JQuery, you match an id with#and a class with.. It is probable that the browser is getting confused because there are multipledivs with the idnewdiv. Additionally, all HTML elements are shown by default unless they are explicitly hidden. As a result, you’re telling the browser to slide down an element that is already being displayed, which is why it’s doing nothing. I’d recommend adding some CSS tonewdivto make it hidden by default (display: none;).cont_div is displayed on the page (top red one on the image). Tried to put the content in variables or make the div invisible – nothing worked.
In your
$.ajaxcall, I’d recommend addingdataType: "json"and not returning raw HTML in your AJAX function. This approach works better if you want to return status information (what if there was an error while accessing the database?), and will help you separate the content from the information. This way, you can design the entire web page in plain old HTML, and then add/remove HTML elements in Javascript based on the data returned from the server. I like to think of all AJAX calls as potential API calls from third parties. If someone else was to access that script, would they want your HTML too, or just the information?For more information on JSON, check out this quick tutorial: http://secretgeek.net/json_3mins.asp. You may not have known it, but you already made a JSON object in your
$.ajaxcall.Only 10 messages should be displayed on one page.
Like just about everything in the programming world, there are many ways to do this. One method would be to always prepend the new messages to the top of the list, and then remove the old ones with JQuery’s
gtselector (http://api.jquery.com/gt-selector/). For example, you could add this line to yoursuccessfunction, which removes alldivtags with the classmsgidthat have an index (position in their parent) greater than 5:$("div.msgid:gt(5)").remove();By the way, welcome to the web world! Keep playing around, and keep the questions coming.