简体   繁体   中英

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM