Load more posts using ajax, php - javascript

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.

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);

Getting the value of dropdownlist in php

I have the following the html/php code :
<!DOCTYPE html>
<html>
<head>
<title>Voiture</title>
</head>
<body>
Welcome<br>
<form method="post" action="">
Liste de voiture<select name="selected" id="selected">
<?php
$sql = 'select Type from voiture';
$result = $conn->query($sql);
$json = array();
while ($row = $result->fetch_assoc()) {
if(!in_array($row['Type'], $json)){
$json[] = $row['Type'];
echo '<option name = "'.$row['Type'].'">'.$row['Type'].'</option>';
}
}
?>
</select> <br>
<span id="sel" name="sel"></span>
<table border="1">
<tr id="header">
<td>Type</td>
<td>Model</td>
<td>Couleur</td>
<td>Prix</td>
<td>User</td>
<td>Action</td>
</tr>
</table>
<input type="submit" name="submit" hidden>
</form>
<script src="jquery-3.2.1.js"></script>
<script>
$(function(){
$('#selected').on('change',function(){
$('#sel').text(document.getElementById('selected').value);
$.getJSON('phpVoiture.php',function(data){
for (var x = 0 ; x < data.length ; x++){
$('<tr><td>'+data[x]['type']+'</td>'+'<td>'+data[x]['Model']+
'</td><td>'+data[x]['Couleur']+'</td>'+
'<td>'+data[x]['Prix']+'</td>'+'<td></td></tr>').insertAfter($('#header'));
}
});
});
});
</script>
</body>
</html>
And the following php page :
<?php
require_once ('./dbConnect.php');
include ('./Voiture.php');
$sel = $_POST['selected'];
$conn = mysqli_connect(servername, username, password, db ,port);
$query = "select * from voiture where Type = '".sel."'";
$result = mysqli_query($conn, $query);
$json = array();
if(mysqli_num_rows($result)>0){
while($row = mysqli_fetch_assoc($result)){
$json[] = [
'type' => $row['Type'],
'model' => $row['Model'],
'couleur' => $row['Couleur'],
'prix' => $row['Prix']
];
}
}
else{
echo mysqli_num_rows($result);
}
echo json_encode($json);
The problem is that when I select an option in the drop down list nothing happens. I want the query in the second php page to select the cars that have the type that I selected in the drop down list. I tried troubleshooting by echo an alert in both pages that have the value of the selected option, but this step also failed, so I think there is an issue with retrieving the value of the selected option. Any help would be appreciated.
You're not sending the selected value to the server. Add it to the AJAX call:
$.getJSON('phpVoiture.php', { selected: $('#selected').val() }, function(data){
//...
});
Also, your <option> elements don't have values. You used name instead, but that belongs on the <select>. Use value:
echo '<option value="'.$row['Type'].'">'.$row['Type'].'</option>';
Additionally, you're using a GET request instead of a POST request. So you need to look for the value in the $_GET array:
$sel = $_GET['selected'];
You have other typos too, such as an incorrect use of a variable in PHP:
"...".sel."..."
would be:
"...".$sel."..."
Though this brings up a point about SQL injection. You really shouldn't be directly concatenating the variable like that at all. Instead, use prepared statements with query parameters.
It's entirely possible that there continue to be other mistakes in the code I simply haven't spotted yet. You'll want your debugging to include two things:
Looking at your PHP logs for errors.
Using your browser's debugging tools to observe the AJAX request/response.

AJAX AND SQL Duplicate results

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.

Get mysql column of a clicked item

I have searched endlessly for an answer but have found none. I am trying to get the id of a clicked item. The item that I am clicking is from mysql database and has been displayed through a for loop. When the item is clicked I am taken to another page. In this page I want to utilize the id from the clicked item to get other information from that row in mysql database; this much I can do. The problem is getting the id from the clicked item and sending it.
This is the most recent way that I tried:
First I displayed the items from mysql.
<?php
$query = "SELECT `video` FROM `challenge_name` ORDER BY `id`";
$result = mysql_query($query);
if($result = mysql_query($query))
{
for($i = 0; $i < mysql_num_rows($result); $i++)
{
$id = $i;
$code = "<div id=\"challenge_preview\"><h7 class=\"challenge_preview_item\"
id=\"challenge_preview_name\"></h7><a href=\"challengeprofile.php\">
<video
class=\"challenge_preview_item\" id=\"challenge_video\"
src=\"".mysql_result($result, $i)."\"></video></a></div>";
echo $code;
}
}
else
{
die('Couldn\'t connect'. mysql_error());
}
?>
Than I put the id in a hidden form so that I could attempt to POST it to the other page:
<form action="<?php echo $current_file; ?>" method="POST">
<input type="hidden" name="id" value="14">
</form>
On the script.php file that is included in both pages, I put
$(#challenge_video).click(function(){ <?php $id = $_POST['id']; ?> ;});
And on the page that the id is being posted to I put
<?php
include 'script.php';
echo getChallengeData('name', 'id', $id)
?>
Please help, Thank you
These are the edits
<div id='challenge_previews'>
<?php
$query = "SELECT `video` FROM `challenge_name` ORDER BY `id`";
$result = mysql_query($query);
if($result = mysql_query($query))
{
for($i = 0; $i < mysql_num_rows($result); $i++)
{
$id = $i;
echo "<div id=\"challenge_preview\"><video class=\"challenge_preview_item challenge_video\" src=\"".mysql_result($result, $i)."\"></video></div>";
}
}
else
{
die('Couldn\'t connect'. mysql_error());
}
?>
<form action="<?php echo $current_file; ?>" method="GET">
<input type="hidden" name="id" value="14">
</form>
</div>
This is the code for page 2
<h1 id="challenge_profile_name">
<?php
$id = substr(base64_decode($_GET['id']),6);
echo getChallengeData('name', 'id', $id);
?>
</h1>
This is the code for the getChallengeData method in the core.inc.php
function getChallengeData($field1, $field2, $field3)
{
$query = "SELECT `$field1` FROM `challenge_name` WHERE `$field2` = '$field3'";
if($query_run = mysql_query($query))
{
if($query_result = mysql_result($query_run, 0, $field1))
{
return $query_result;
}
}
}
That error that I'm getting has to do with the implementation of the getChallengeData method on page 2. The error says
Warning: mysql_result(): Unable to jump to row 0 on MySQL result index 10 in C:\xampp\htdocs\ChallengeNetworkWebsite\core.inc.php on line 42

Best way to pass sensitive variables on click event?

I am looking for a secure way of passing sensitive variables to a php file via ajax. At the moment i have been using data attributes but the values can be changed using something like firebug.
HTML:
<div class="strip">
<?php
if($hide == 0) {
echo '<h2 class="action" data-type="1" data-id="<?php echo $id; ?>" data-action="0">Hide Business</h2>';
}
if($hide == 1) {
echo '<h2 class="action" data-type="1" data-id="<?php echo $id; ?>" data-action="1">Un-Hide Business</h2>';
}
?>
<h2 class="action" data-type="1" data-id="<?php echo $id; ?>" data-action="2">Delete Business</h2>
</div>
JavaScript/JQuery:
$(".action").click(function() {
var type = $(this).data("type");
var id = $(this).data("id");
var action = $(this).data("action");
$.ajax({
url : 'assets/php/confirm.php',
type : 'POST',
data : "type="+type+"&action="+action+"&ids="+id,
success : function (result) {
alert(result);
}
});
});
PHP:
if(isset($_POST['type'], $_POST['action'], $_POST['ids'])) {
$type = $_POST['type'];
$action = $_POST['action'];
$ids = explode(",", $_POST['ids']);
$count = count($ids);
if($type == 0) {
if($action == 1) {
$stmt = $mysqli->prepare("DELETE FROM deals WHERE id=?");
} else {
$stmt = $mysqli->prepare("UPDATE deals SET hide=0 WHERE id=?");
}
} else {
if($action == 1) {
$stmt = $mysqli->prepare("DELETE FROM businesses WHERE id=?");
} else {
$stmt = $mysqli->prepare("UPDATE businesses SET hide=0 WHERE id=?");
}
}
for($i = 0; $i < $count; $i++) {
$stmt->bind_param('s', $ids[$i]);
$stmt->execute();
$stmt->close();
}
echo 'Success updated '.$_POST['ids'];
}
The variables that need to be secure are the data-type, data-id, data-action values. Reason being i dont want the wrong database entries being deleted.
I dont know of any alternatives, so any help would be great.
If you want to stop the user changing them, then you can't get them from the user at all. Store the data on the server instead.
If you want to limit what values you'll accept from the user, then limit them on the server. Perform authentication and authorization. Make sure the values being changed are ones the logged in user is allowed to change.
As your code on the client - inside the browser - can not be hidden, you should secure the connection between client and web server - use SSL/TSL for that...

Categories

Resources