How to load data on page scroll in CodeIgniter 4 with Ajax and jQuery.

             We have used the CodeIgniter framework with Ajax and jQuery to create infinite scroll pagination by loading dynamic data on page scroll. To load data on page scroll, we use the jQuery scroll event, triggering an Ajax request to a CodeIgniter controller method. The controller sends the limit of data fetching and the last offset to the model, which fetches data from the MySQL table and returns it to the controller. The controller then sends the data to the view file, where the Ajax request displays it on page scroll. This process continues with each page scroll, loading dynamic data without refreshing the webpage.

Codeigniter 4 Ajax -  Load More Data on Page Scroll in CodeIgniter 4 using Ajax jQuery

Table Of Content

1 Prerequisites

1.) PHP version of >=8.1
2.) Mysql

2 Introduction

In this Load Data on Page Scroll in CodeIgniter 4 using Ajax jQuery tutorial, we'll demonstrate how to use jQuery Ajax to load more data dynamically as the user scrolls the page.

3 Create / Install a Codeigniter 4 Project

3.1 Install Codeigniter 4 Project

Make sure you have Composer installed. Run the following command to create a new CodeIgniter project:

composer create-project codeigniter4/appstarter ci-4-ajax-load-more-app

Then, navigate to your project directory:

cd ci-4-ajax-load-more-app

3.2 Configure Environment (.env)

After installing CodeIgniter 4, rename the env file to .env for environment variables.

sudo cp env .env

Switch to development mode by updating the .env file:

# CI_ENVIRONMENT = production
CI_ENVIRONMENT = development


Now application is in development mode.

4 Create Migration and Model

To manage user data, create a migration for the users table and a model.

php spark make:model UserModel

Edit UserModel.php to define the users table structure. Then, create the migration for the table:

<?php
namespace App\Models;

use CodeIgniter\Model;

class UserModel extends Model
{
    protected $table = 'users';
    protected $primaryKey = 'id';
    protected $allowedFields = ['name', 'email', 'created_at'];
}

Create a migration file for the users table:

php spark make:migration AddUser

Define the table structure in the migration file.

<?php
namespace App\Database\Migrations;

use CodeIgniter\Database\Migration;

class AddUser extends Migration
{
    public function up()
    {
        $this->forge->addField([
            'id' => [
                'type' => 'BIGINT',
                'constraint' => 255,
                'unsigned' => true,
                'auto_increment' => true
            ],
            'name' => [
                'type' => 'VARCHAR',
                'constraint' => '255',
            ],
            'email' => [
                'type' => 'longtext'
            ],
            'created_at' => [
                'type' => 'TIMESTAMP',
                'null' => true
            ],
            'updated_at' => [
                'type' => 'TIMESTAMP',
                'null' => true
            ],
        ]);
        $this->forge->addPrimaryKey('id');
        $this->forge->createTable('users');
    }

    public function down()
    {
        $this->forge->dropTable('users');
    }
}


Run the migration:

php spark migrate

5 Create Database Seeder

To populate the users table with test data, use the seeder class.
Run this command:

php spark make:seeder UserSeeder

Edit UserSeeder.php to generate 100 fake users using the Faker library, then run the seeder:

<?php
namespace App\Database\Seeds;

use CodeIgniter\Database\Seeder;
use CodeIgniter\I18n\Time;
use App\Models\UserModel;
class UserSeeder extends Seeder
{
    public function run()
    {
        $user = new UserModel;
        $faker = \Faker\Factory::create();

        for ($i = 0; $i < 100; $i++) {
          $user->save(
                [
                    'name'        =>    $faker->name,
                    'email'       =>    $faker->email,
                    'created_at'  =>    Time::createFromTimestamp($faker->unixTime()),
                    'updated_at'  =>    Time::now()
                ]
            );
        }
    }
}

Run this below command to insert the data.

php spark db:seed UserSeeder

6 Create New Controller - UserController

Create a controller to handle data requests.

php spark make:controller UserController

In UserController.php, define methods to load data on page scroll. The onScrollLoadMore method will handle Ajax requests, loading more data based on the page offset.

<?php
namespace App\Controllers;

use App\Controllers\BaseController;
use CodeIgniter\HTTP\ResponseInterface;
use App\Models\UserModel;


class UserController extends BaseController
{
    public function __construct()
    {
        $this->userModel = new UserModel();
    }
    public function index() {
        $data = [
            'users' => $this->userModel->orderBy('id', 'desc')->paginate(4),
            'pager' => $this->userModel->pager
        ];
        return view('index', $data);
    }
 
   public function onScrollLoadMore(){
        $limit = 4; 
        $start=$limit * ($this->request->getVar('page')-1);
        $data['users'] = $this->loadMoreData($limit,$start);
        return view('load_users', $data);
   }
   
   function loadMoreData($limit,$start)
   {
        $builder = $this->userModel->select('*')->orderBy('id', 'desc')->limit($limit,$start)->get();
        return $builder->getResult();
   }    
}
?>

7 Create a View

Create a view file index.php in the app/Views directory to display the data:

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <title>Ajax Load More Data on Page Scroll in Codeigniter 4</title>
        <style>
            body {
                height: 1000px;
            }
        </style>
    </head>
    
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    
    <body>
        <div class="container">
            <?php if($users)
                 foreach($users as $data) { ?>
                    <div class="card mb-3">
                       <h3><?php echo $data['name']; ?></h3>
                    </div>
                <?php } ?>
            <div id="loadMoreBlock"></div>
        </div>
    </body>
    
    
    <script>
        var baseURL = "<?php echo base_url(); ?>";
        var page = 1;
        var triggerScrollLoader = true;
        var isLoading = false;
    
        $(window).scroll(function () {
            if ($(window).scrollTop() + $(window).height() >= $(document).height() - 555) {
                if (isLoading == false) {
                    isLoading = true;
                    page++;
                    if (triggerScrollLoader) {
                        initLoadMore(page);
                    }
                }
            }
        });
    
        function initLoadMore(page) {
            $.ajax({
                url: baseURL+"onScrollLoadMore?page=" + page,
                type: "GET",
                dataType: "html",
            }).done(function (data) {
                isLoading = false;
                if (data.length == 0) {
                    triggerScrollLoader = false;
                    $('#loader').hide();
                    return;
                }
                $('#loader').hide();
                $('#loadMoreBlock').append(data).show('slow');
            }).fail(function (jqXHR, ajaxOptions, thrownError) {
                console.log('Nothing to display');
            });
        }
    </script>
    </html>

Create a view file load_users.php in the app/Views directory to display the load more data:

<?php 
if($users)
    foreach($users as $data)
    {
?>
        <div class="card mb-3">
            <h3><?php echo $data->name; ?></h3>
        </div>
<?php 
    } ?>

8 Define a Route

In app/Config/Routes.php, define the routes for the controller methods:

use CodeIgniter\Router\RouteCollection;

/**
 * @var RouteCollection $routes
 */
$routes->get('/', 'Home::index');
$routes->get('users', 'UserController::index');
$routes->get('onScrollLoadMore', 'UserController::onScrollLoadMore');

9 Folder Structure

The structure for this CodeIgniter project:

10 Run Web Server to Test the App

Use the following command to start the web server and test the application:

php spark serve

Visit http://localhost:8080/index.php to see the app in action.

11 Conclusion

To provide a seamless user experience for loading more data without page refresh, using Ajax and jQuery for infinite scroll pagination is a great option. This tutorial demonstrated how to Load Data on Page Scroll in CodeIgniter 4 using Ajax jQuery efficiently.

Tags