AJAX AND SQL Duplicate results - javascript

I Have problem, I have ajax request and php script, when I click button, results duplicate.
HTML AND JS:
$("#more-news").click(function(e) {
e.preventDefault();
$.ajax({ //create an ajax request to load_page.php
type: "GET",
url: "/getnews.php",
dataType: "html", //expect html to be returned
data: {
lang: lng,
last_id: last_id,
ids: dataN
},
success: function(response){
var content = document.getElementById("responsecontainer");
content.innerHTML = content.innerHTML+response;
//$("#responsecontainer").html(response);
$('#more-news').attr('data-lim', Number($('#more-news').attr('data-lim')) + 10);
//alert(response);
}
});
});
<div id="responsecontainer"></div>
<div style="text-align: center;">
<button id="more-news" data-lim="10" style="border:none" class="btn-type-one">
<span class="more"><?= $this->trans->t('More'); ?></span>
</button>
</div>
<?php
$dtTTNews = [];
foreach ($front_page_news as $item) {
$dtTTNews[] = $item['id'];
?>
<? } ?>
<script>
var dataN = <?php echo json_encode($dtTTNews); ?>;
var lng = '<?=$lang?>';
var last_id = '<?=end($dtTTNews)?>';
</script>
PHP:
$ids = $_GET['ids'];
$dtNow = new \DateTime('now');
$db->set_charset("utf8");
$news_id = abs($db->real_escape_string($_GET['last_id']));
$date_now = new \DateTime('now');
$in = join(',', array_fill(0, count($ids), '?'));
//$q = $db->query("select * count(*)
$q = $db->query('SELECT * FROM news WHERE id < "'.$news_id.'" ORDER BY date_show DESC LIMIT 3');
//$q = $db->query('SELECT id, title_ru, title_md, body_ru, body_md, is_video, thumb_ru, thumb_md, date_show,title_ru, title_md
//FROM news GROUP BY id');
$lang = (isset($_GET['lang']) && $_GET['lang'] == 'ru') ? 'ru' : 'md';
$isHidden = false;
if($q->num_rows > 0):
while($item = $q->fetch_assoc()):
$dtNews = new \DateTime($item['date_show']);
if ($dtNews > $dtNow) {
$isHidden = true;
break;
}
$qs = $db->query("SELECT * FROM news_categories WHERE news_id = " . $item['id']);
if($qs->num_rows > 0) {
$dd = $qs->fetch_assoc();
$qss = $db->query("SELECT * FROM categories WHERE id = " . $dd['categories_id']);
$dd2 = $qss->fetch_assoc();
if(in_array('Скрытые новости', $dd2) || in_array('Hidden News', $dd2)) {
$isHidden = true;
break;
}
}
$dtShow = $dtNews->format("Y-m-d");
//$dtShow = \Noitools\Utils::timeFromPost($item['date_show'], $lang);
if($item['active'] == '1'):
if($item['body_' . $lang] != ''):
if(!$isHidden):
?>
<div class="article-item" data-news="<?= $item['id']; ?>">
<a href="/<?=$lang?>/news_id/<?=$item['id']?>"
class="link-img-wrap<?= ($item['is_video']) ? ' video-icon-medium' : ''; ?>">
<img src="/uploads/newsthumbs/760_500/<?=$item['id']?>.jpg"
alt="">
</a>
<div class="details-post">
<i><?=$dtShow?></i>
<?= $dd2['title_' . $lang] ?>;
</div>
<h3><a href="/<?=$lang?>/news_id/<?=$item['id']?>"><span
class="detail-title"><?=$dtShow?></span> <?= $item['title_' . $lang] ?></a></h3>
<p class="small-text">
<?= mb_substr(strip_tags($item['body_' . $lang]), 0, 180,
'utf-8') ?>
</p>
</div>
<?php endif; endif; endif; endwhile; endif; ?>
How I Can Fix this duplicates? I think, because LIMIT 3, when I click button he load 3 same elements ..
I want when I click button more, load 3 more news

On first glance it appears that the problem lies with you SQL statement:
$q = $db->query('SELECT * FROM news WHERE id < "'.$news_id.'" ORDER BY date_show DESC LIMIT 3');
Since you are appending the Ajax results each time, you only want to fetch news results that you haven't fetched before. By using less than, you are fetching ALL results less than $news_id, each time.
What you need to do is to window your results. In other words, you need to have a starting id and then fetch several more records. So:
$q = $db->query('SELECT * FROM news WHERE id > "'.$news_id.'" ORDER BY date_show DESC LIMIT 3');
And as long as you keep passing the new id (last_id in your javascript), as the last record fetched, it should work.
The other problem you may have is your ordering. You need to order the same way that you are comparing. If comparing by id, you need:
$q = $db->query('SELECT * FROM news WHERE id > "'.$news_id.'" ORDER BY id ASC LIMIT 3');
If comparing by date then something like:
$q = $db->query('SELECT * FROM news WHERE date_show < "'.$date_show.'" ORDER BY date_show DESC LIMIT 3');
You can't mix both id and date_show. Unless you know that id and date_show are strictly in the same order.

Related

how to call ajax pagination function

I've succeeded display the data what I want based on the select box, but why is my pagination not working?
The index.php display with pagination not working
this is my ajax script to load data and pagination function
<div class="col-md-12">
<div class="table-responsive" id="show-level"></div>
</div>
</div>
</body>
</html>
<!---jQuery ajax load rcords using select box --->
<script type="text/javascript">
$(document).ready(function(){
load_data();
function load_data(page){
$(".level").on("change", function(){
var levelname = $(this).val();
if (levelname !== "") {
$.ajax({
url : "display.php",
type:"POST",
cache:false,
data:{levelname:levelname, page:page},
success:function(data){
$("#show-level").html(data);
}
});
}else{
$("#show-level").html(" ");
}
});
}
$(document).on('click', '.pagination_link', function(){
var page = $(this).attr("id");
load_data(page);
});
});
</script>
and then this is my display.php where the pagination function is set
$output .= "</table>";
$page_query = "SELECT * FROM list WHERE level = 'sulit'";
$page_result = mysqli_query($con, $page_query);
$total_records = mysqli_num_rows($page_result);
$total_pages = ceil($total_records/$record_per_page);
for($i=1; $i<=$total_pages; $i++)
{
$output .= "<span class='pagination_link' style='cursor:pointer; padding:6px; border:1px solid #ccc;' id='".$i."'>".$i."</span>";
}
$output .= '</div><br /><br />';
echo $output;
}else{
echo "No records found";
}
?>
If $records_per_page is 10, and the number of total records is 100, the below will always give you the first 10 items.
$total_records = mysqli_num_rows($page_result);
$total_pages = ceil($total_records/$record_per_page);
for($i=1; $i<=$total_pages; $i++) {
...
You should look at limiting the number of results and offsetting them in your SQL instead. For instance, you can limit your number of rows to 10, and then offset the results by the page number you are currently on (*10).
Here is what the statement would look like for page 2:
SELECT * FROM list WHERE level = 'sulit' LIMIT 10 OFFSET 10
So your code could look something like (I haven't tested this - but I think it should be about right):
$offset = $current_page * $records_per_page;
$page_query = "SELECT * FROM list WHERE level = 'sulit' LIMIT ? OFFSET ?";
$page_result = mysqli_prepare($con, $page_query);
mysqli_stmt_bind_param($page_result, 'ii', $records_per_page, $offset);
mysqli_stmt_execute($page_query);

Php updating a span using javascript/ajax is not working properly

I am updating a span using below script but it is working if condition is false and if condition is true it does not update.
What i observed that it executes the same false condition and when i click the second time it updates the quantity but less 1 number than the actual quantity of records in the database.
Like total records are 2 and when i click submit the script runs and if condition is true in the database records are updated = 3 but in the span it shows 2.
When i click 2nd time and in the database records are = 4 and in the span it shows 3.
Button where i click and run the script
<input onclick='updateTitems("1");' type="submit" class="btn-style-2 mg-left-5" value="ADD TO CART">
script
<script>
function updateTitems(id) {
var uid = "<?php echo $ses_mem; ?>";
$.ajax({
type: "GET",
url: 'inc/menu_update_total_items.php',
data: "id=" + id + "&uid=" + uid,
success: function(data) {
$('.summary12').html(data);
}
});
}
</script>
menu_update_total_items.php
$user_id = $_GET['uid'];
$item = "select count(*) as records
from orders_temp
where user_id = '".$user_id."'
";
$itemq = $dba->query($item);
$itemr = $itemq->fetch_assoc();
$count = $itemr['records'];
---------------------------------
$itemx = "select count(*) as records
from orders_temp
where date = now()
and user_id = '".$user_id."'
";
$itemqx = $dba->query($itemx);
$itemrx = $itemqx->fetch_assoc();
$check = $itemrx['records'];
<span class="summary12"><!-- class of javascript -->
<?php
if ($check == 1){
echo $count+1;
}else{
echo $count;
}
?>
Items
</span>
After trying lot of things i came up with the following solution and the issue has been solved.
Please need your opinion on this. Thanks
Button
<input onclick='updateTitems();' type="submit" class="btn-style-2 mg-left-5" value="ADD TO CART">
Script
function updateTitems(){
$.ajax({
url: "menu_update_total_items.php",
cache: false,
success: function(data){
$(".summary12").html(data);
//div or span reload script after success
setInterval(function () {
$('.summary12').load('inc/menu_update_total_items.php');
}, 1000);
}
});
}
menu_update_total_items.php
<?php
#session_start();
include ("inc/db.php");
$ses_mem = session_id();
$items = "select count(*) as trecords
from orders_temp
where user_id = '".$ses_mem."' ";
$item = $dba->query($items);
$count = $toitemszx->fetch_assoc();
?>
<a href="cart/review" class="cart-link">
<i class="fa fa-shopping-basket"></i>
<?php echo $count['trecords']; ?>
Items
</a>

I can not display the data from my json_encode ($.each)

Hello to every one and thank you for your time.
My problem is that i can not display the json_encode from my php database but in my chrome the data is appear.
The $.each is not dispaly all only one
enter image description here
now the code for the php :
comment.php
$data = $_REQUEST;
$photo_id =38;//$data['photo_id_comment'];
$con = mysqli_connect('localhost','root','','gallery');
$sql = "SELECT * FROM comments";
$sql .= " WHERE photo_id = " . $database->escape_string($photo_id);
$sql .= " ORDER BY photo_id ASC";
$result = mysqli_query( $con,$sql);
$arr = array();
$row_count = mysqli_num_rows($result);
while ($row = mysqli_fetch_array($result)) {
array_push($arr , $row);
}
mysqli_close($con);
echo json_encode($arr);
And the ajax to retrieve data is: script.js
function refreshComment() {
requestData = $("#photo_id_comment").serialize();
$.ajax({
url: "http://localhost/udemy/app_php/includes/comment.php",
type: "get",
data: requestData,
dataType: "text",
success : function (data) {
jQuery.each(data, function(index, item) {
//now you can access properties using dot notation
$('#chat_box').val( $('#chat_box').val() + item.body + '\n');
/* $('#author_comment').html(item.author);
$('#chat_box').html(item.body);*/
});
},
error: function (http, status, error) {
alert('Some error occurred :'+error);
}
});
return false;
}
setInterval( refreshComment , 5000 );
And the html where the data is not display is: photo.php.
<div class="media">
<a class="pull-left" href="#">
<img class="media-object" src="http://placehold.it/64x64" alt="">
</a>
<div class="media-body">
<h4 id="author_comment" class="media-heading"></h4>
<p id="chat_box"></p>
<p class="text-info">This is post at: </p>
</div>
</div>
Please try this one,
$sql = "SELECT * FROM comments WHERE photo_id = " . $database->escape_string($photo_id) ORDER BY photo_id ASC";
$result = mysqli_query( $con,$sql);
$arr = array();
while ($row = mysqli_fetch_array($result)){
$arr[] = $row;
}
echo json_encode($arr);
and change ,
dataType:'json' instead of dataType:'text'
in script.
change dataType:text to dataType:JSON
EDIT
use this instead of $.each
for(var i = 0;i < data.length ; i++)
{
/*access data as data[i].orfeas*/
}
PHP
$array = array();
$i = 0;`
foreach($res as $r){
$array[$i] = $r;
$i++;
}
header('Content-Type:Application/json');
echo json_encode($array);
EDIT2
USE Header to help jQuery to identify the response type and then jQuery will parse the JSON and you can access it by using a loop above mentioned
in your script.js file make change on success function of ajax:-
success : function (data) {
$.each($.parseJSON(data), function(key,item){
$('#chat_box').val( $('#chat_box').val() + item.body + '\n');
});
}

Load more posts using ajax, php

I am displaying posts in a table and then trying to call more posts using ajax, but I am encountering problems here, on clicking show more same posts appear again so how to call next posts by id, and another problem is on clicking show more it changes to loading and remains their, I want it to hide after posts have been loaded.
I am calling the whole table again I think I would be better to call only rows. Here are my two files
index.php
<script type="text/javascript">
$(document).ready(function(){
$(document).on('click','.show_more',function(){
var ID = $(this).attr('id');
$('.show_more').hide();
$('.loding').show();
$.ajax({
type:'POST',
url:'ajax_more.php',
data:'id='+ID,
success:function(html){
$('#show_more_main'+ID).remove();
$('#posts').append(html);
}
});
});
});
</script>
$sql = "SELECT * FROM posts order by id desc limit 6";
$query = $db->prepare($sql);
$query->execute();
$row = $query->fetch(PDO::FETCH_ASSOC);
$ID = $row['id'];
<div id="posts">
<table>
<tr>
<?php do { //horizontal looper?>
<td>
<div>id</div>
<div>title</div>
<div>body</div>
<div>date</div>
</td>
<?php
$row = $query->fetch(PDO::FETCH_ASSOC);
if (!isset($nested_List)) {
$nested_List= 1;
}
if (isset($row) && is_array($row) && $nested_List++%3==0) {
echo "</tr><tr>";
}
} while ($row); //end horizontal looper
?>
</table>
<div class="show_more_main" id="show_more_main<?php echo $ID; ?>">
<span id="<?php echo $ID; ?>" class="show_more" title="Load more posts">Show more</span>
<span class="loding" style="display: none;"><span class="loding_txt">Loading…</span></span>
</div>
</div>
ajax_more.php
<?php
include('db.php');
if(isset($_POST["id"]) && !empty($_POST["id"])){
$sql = "SELECT * FROM posts order by id desc limit 6";
$query = $db->prepare($sql);
$query->execute();
$row = $query->fetch(PDO::FETCH_ASSOC);
$ID = $row['id'];
?>
<table>
<tr>
<?php do { //horizontal looper?>
<td>
<div>id</div>
<div>title</div>
<div>body</div>
<div>date</div>
</td>
<?php
$row = $query->fetch(PDO::FETCH_ASSOC);
if (!isset($nested_List)) {
$nested_List= 1;
}
if (isset($row) && is_array($row) && $nested_List++%3==0) {
echo "</tr><tr>";
}
} while ($row); //end horizontal looper
?>
</table>
<div class="show_more_main" id="show_more_main<?php echo $ID; ?>">
<span id="<?php echo $ID; ?>" class="show_more" title="Load more posts">Show more</span>
<span class="loding" style="display: none;"><span class="loding_txt">Loading…</span></span>
</div>
<?php
}
?>
You will have to use OFFSET and LIMIT for your SQL Query. Currently you are using SELECT * FROM posts order by id desc limit 6. That isn't going to load you "more", as it will always only fetch the 6 biggest posts (ordered descending by their id).
You have a couple of problems.
When your AJAX call completes and you want the loading message to disappear, you need to hide that in your success callback of the ajax call. Like so:
$(document).on('click','.show_more',function(){
var ID = $(this).attr('id');
$('.show_more').hide();
$('.loding').show();
$.ajax({
type:'POST',
url:'ajax_more.php',
data:'id='+ID,
success:function(html){
$('#show_more_main'+ID).remove();
$('#posts').append(html);
$('.loding').hide();
}
});
});
In your SQL, you aren't doing anything to select alternative posts because after checking if the ID was sent. You don't do anything with it. Change your SQL to select id's greater than it if it exists.
$postedId = (int)$_POST['id'];
$sql = "SELECT * FROM posts order by id desc WHERE id > $postedId limit 6";
You want to make sure that the id is escaped to prevent any sort of SQL injection. So as a simple measure, I converted it to an integer (I am assuming on that). Otherwise, you should look into using prepared statements for your queries to prevent SQL injection. http://php.net/manual/en/mysqli.quickstart.prepared-statements.php
Your SQL query needs to be fixed. Lets say you want to load the next 6 (ordered in descending order by ID). To do this, you should send some kind of variable like offset. Then you can say:
$sql = "SELECT * FROM posts ORDER BY id DESC LIMIT $offset, $end;"
Where $end = $offset + 6;
Before using this, though, be sure to check that $offset is numeric to prevent SQL injection. This could be implemented using:
if(i!sset($_POST["id"]) || empty($_POST["id"])){
die("No ID value present.");
}
$offset = (isset($_POST['offset']) ? $_POST['offset'] : 0);
if(!is_numeric($offset)){
die("Abnormal input detected.");
} else {
// Input is numeric
$offset = intval($offset);
}
$end = $offset + 6;
$sql = "SELECT * FROM posts ORDER BY id DESC LIMIT $offset, $end;"
/* Your code for actually querying the DB and processing results */
Note: I'm not too familiar with PDO, however, this should be compatible with PDO and safe/secure to use.

Pull down updates when user click on updates

Hello people please help me with this! what i want to achieve is similar to twitter update notification bar that displays the number of new tweets and when you click on it; it drops the latest tweets on the previous tweets. i have been banging my head over this for days now, Here is what i tried.
//feed.php
<?php
session_start();
$cxn = mysqli_connect('localhost','root','','my_db');
$query = "SELECT insertion_time FROM feeds ORDER BY insertion_time DESC LIMIT 0,1";
$result = mysqli_query($cxn, $query) or die (mysqli_error($cxn));
$latest_feed = mysqli_fetch_assoc($result);
$_SESSION['latest_id'] = $latest_feed['insertion_time'];
$latest_news = $_SESSION['latest_id'];
echo $check = <<<JS_SCRIPT
<script>
interval = setInterval(function(){
check_update($latest_news);
},5000);
</script>
JS_SCRIPT;
?>
<script src='jquery.js'></script>
<script>
function check_update(old_feed)
{
$.post('server.php',{get_num_update: old_feed},function(data){
$("#update_bar").html(data);
}); //checks for number of updates
$.post('server.php',{retrieve_update: old_feed},function(data){
$("#hidden_div").html(data);
}); //retrieves the update into a div
}
$(function(){
$("#update_bar").click(function(){
$("#hidden_div").prependTo("#news_feed_container").fadeIn(500);
});
});
</script>
//server.php
if(isset($_POST['get_num_update']) && !empty($_POST['get_num_update']) && is_numeric($_POST['get_num_update']))
{
$old_feed = $_POST['get_num_update'];
$query = "SELECT id FROM feeds WHERE insertion_time > $old_feed ORDER BY insertion_time DESC";
$exec = mysqli_query($cxn, $query) or die(mysqli_error($cxn));
$num_updates = mysqli_num_rows($exec);
echo ($num_updates > 0) ? $num_updates.' new updates' : '';
}
if(isset($_POST['retrieve_update']) && !empty($_POST['retrieve_update']) && is_numeric($_POST['retrieve_update']))
{
while($result = mysqli_fetch_assoc($exec))
{
extract($result);
echo <<<HTML
//inserting the variable into html
HTML;
}
}
//
when the user clicks on the update_bar div which will be displaying something like '5 new updates' i want the update to pull down the latest feed from the hidden div, so everything doesn't really work as i would expect someone please help me out
Not tested, but it should approximately work...
//feed.php
<?php
session_start();
$cxn = mysqli_connect('localhost','root','','my_db');
$query = "SELECT insertion_time FROM feeds ORDER BY insertion_time DESC LIMIT 0,1";
$result = mysqli_query($cxn, $query) or die (mysqli_error($cxn));
$latest_feed = mysqli_fetch_assoc($result);
$_SESSION['latest_id'] = $latest_feed['insertion_time'];
$latest_news = $_SESSION['latest_id'];
echo $check = <<<JS_SCRIPT
<script>
// made the parameter of check_update a js variable and not hard coded in PHP
var latest_new=$latest_news;
// add a temp js variable for the last feed received (but not displayed)
var last_received=$latest_news;
interval = setInterval(function(){
check_update(latest_news);
},5000);
</script>
JS_SCRIPT;
?>
<script src='jquery.js'></script>
<script>
function check_update(old_feed)
{
// change your AJAX request to deal with JSON data and received several informations (number of new feed, insertion time of the last one)
$.post('server.php',{get_num_update: old_feed},function(data){
$("#update_bar").html(data.number_recents+" new updates.");
last_received=data.last_time;
},'json');
$.post('server.php',{retrieve_update: old_feed},function(data){
$("#hidden_div").html(data);
}); //retrieves the update into a div
}
$(function(){
$("#update_bar").click(function(){
$("#hidden_div").prependTo("#news_feed_container").fadeIn(500);
latest_new=last_received;
});
});
</script>
//server.php
if(isset($_POST['get_num_update']) && !empty(get_num_update']))
{
// header to serve JSON data
header('application/json');
$old_feed = $_POST['get_num_update'];
// request the number of new feed and the mst recent insertion time
$query = "SELECT count(*) as number,max(insertion_time) as last_time FROM feeds WHERE insertion_time > $old_feed ORDER BY insertion_time DESC";
$exec = mysqli_query($cxn, $query) or die(mysqli_error($cxn));
$feed_info = mysqli_fetch_assoc($exec);
//write the JSON data
echo '{"number_recents":'.$feed_info['number'].',"last_time":'.last_time.'}';
} else if(isset($_POST['retrieve_update']) && !empty($_POST['retrieve_update']) && is_numeric($_POST['retrieve_update']))
{
while($result = mysqli_fetch_assoc($exec))
{
extract($result);
echo <<<HTML
//inserting the variable into html
HTML;
}
}

Categories

Resources