Load more pagination with AngularJS and PHP

Load more pagination allows the users to load new content on a button click. This appends new content with existing contents.

It is the type of infinite pagination where the user has to click the action button to view new records. This load data until records are available.

In this tutorial, I am implementing this functionality on a page with AngularJS and PHP.

Load more pagination with AngularJS and PHP


Contents

  1. Table structure
  2. Configuration
  3. HTML
  4. CSS
  5. PHP
  6. Script
  7. Conclusion

 


1. Table structure

I am using posts table in the tutorial example.

CREATE TABLE `posts` (
  `id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
  `title` varchar(100) NOT NULL,
  `content` text NOT NULL,
  `link` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

2. Configuration

Create a config.php for database connection.

Completed Code

<?php
$host = "localhost"; /* Host name */
$user = "root"; /* User */
$password = ""; /* Password */
$dbname = "tutorial"; /* Database name */

$con = mysqli_connect($host, $user, $password,$dbname);
// Check connection
if (!$con) {
  die("Connection failed: " . mysqli_connect_error());
}

3. HTML

Define ng-controller='fetchCtrl' directive on <div class='container'> within it create post display layout. Specify ng-repeat directive on <div class='post'> to loop on posts scope variable and display data.

Use <h1> element to show Load more button and fetch new records when its gets clicked ng-click='getPosts()'. Also define ng-show='showLoadmore' directive to hide this element when all data is been loaded.

To track current row position create a hidden element and specify ng-model='row' directive which is been updated from the <script>.

Completed Code

<body ng-app='myapp'>
 <div class="container" ng-controller='fetchCtrl'>

  <!-- Post -->
  <div class="post" ng-repeat='post in posts'>
   <h1>{{ post.title }}</h1>
   <p>
   {{ post.shortcontent }}
   </p>
   <a href="{{ post.link }}" class="more" target="_blank">More</a>
  </div>
 
  <h1 class="load-more" ng-show="showLoadmore" ng-click='getPosts()'>{{ buttonText }}</h1>
  <input type="hidden" id="row" ng-model='row'>

 </div>
 
</body>

4. CSS

.container{
  width: 55%;
  margin: 0 auto;
  border: 0px solid black;
  padding: 10px 0px;
}

/* post */
.post{
  width: 97%;
  min-height: 200px;
  padding: 5px;
  border: 1px solid gray;
  margin-bottom: 15px;
}

.post h1{
  letter-spacing: 1px;
  font-weight: normal;
  font-family: sans-serif;
}

.post p{
  letter-spacing: 1px;
  text-overflow: ellipsis;
  line-height: 25px;
}

/* Load more */
.load-more{
  width: 99%;
  background: #15a9ce;
  text-align: center;
  color: white;
  padding: 10px 0px;
  font-family: sans-serif;
}

.load-more:hover{
  cursor: pointer;
}

/* more link */
.more{
  color: blue;
  text-decoration: none;
  letter-spacing: 1px;
  font-size: 16px;
}

5. PHP

Create new getData.php file.

From here, fetch records from posts Table according to POST row and rowperpage value. Initialize an array with response data and return the JSON object.

Completed Code

<?php

// configuration
include 'config.php';

$data = json_decode(file_get_contents("php://input"));

$row = $data->row;
$rowperpage = $data->rowperpage;

// selecting posts
$query = 'SELECT * FROM posts limit '.$row.','.$rowperpage;
$result = mysqli_query($con,$query);

$response_arr = array();

while($datarow = mysqli_fetch_assoc($result)){
 
  $id = $datarow['id'];
  $title = $datarow['title'];
  $content = $datarow['content'];
  $shortcontent = substr($content, 0, 160)."...";
  $link = $datarow['link'];
 
  $response_arr[] = array('id'=>$id,'title'=>$title,'shortcontent'=>$shortcontent,'content'=>$content,'link'=>$link);
 
}

if(count($response_arr) > 0)
  echo json_encode($response_arr);
exit;

6. Script

In the controller first defined 4 variables –

  • $scope.showLoadmore – To show or hide the Load more button. Set default value to true.
  • $scope.row – Default row position. Set default value to 0.
  • $scope.rowperpage – Number of rows to fetch at a time. Set default value to 3.
  • $scope.buttonText – Button visible text.

Define a getPosts() function to get new records by sending $http request. On successfully callback increment $scope.row value by adding $scope.rowperpage.

Add delay while push response in $scope.posts with setTimeout() function and change button text to "Loading..." with $scope.buttonText.

Completed Code

<script src="angular.min.js"></script>
<script>
var fetch = angular.module('myapp', []);

fetch.controller('fetchCtrl', ['$scope', '$http', function ($scope, $http) {

 // Variables
 $scope.showLoadmore = true;
 $scope.row = 0;
 $scope.rowperpage = 3;
 $scope.buttonText = "Load More";
 
 // Fetch data
 $scope.getPosts = function(){
 
  $http({
   method: 'post',
   url: 'getData.php',
   data: {row:$scope.row,rowperpage:$scope.rowperpage}
  }).then(function successCallback(response) {
 
   if(response.data !='' ){
    // Increment row position
    $scope.row+=$scope.rowperpage;
    if($scope.posts != undefined){
     $scope.buttonText = "Loading ...";
     // Set Delay
     setTimeout(function() {
      $scope.$apply(function(){
       // Append data to $scope.posts
       angular.forEach(response.data,function(item) {
        $scope.posts.push(item);
       });
       $scope.buttonText = "Load More";
      });
     },500);
 
    }else{
     $scope.posts = response.data;
    }
   }else{
    $scope.showLoadmore = false;
   }

  });
 }
 // Call function
 $scope.getPosts();
 
}]);

</script>

7. Conclusion

In the demonstration, I created a simple example to show the implementation of load more result on click with AngularJS and PHP.

If you would like to learn load more pagination with jQuery AJAX you can view my earlier tutorial.

If you found this tutorial helpful then don't forget to share.