Create Laravel 8 Auto Load More Data On Page Scroll with AJAX

hello artisan, today we will be going to build an infinity scroll for autoloading data in laravel. We will learn how to create laravel auto load more data on page scroll with ajax.

Create Laravel Project

composer create-project --prefer-dist laravel/laravel blog

Make Database Connection

Go to your project directory and find the .env file and update it like :

.env

DB_CONNECTION=mysql  
DB_HOST=127.0.0.1  
DB_PORT=3306  
DB_DATABASE=laravel_db  
DB_USERNAME=root  
DB_PASSWORD=

Create Model and Run Migration

Run the below command to create the model and also migrate file

php artisan make:model Post -m
Next, update the below code in the database/migrations/#########_create_posts_table.php file
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreatePostsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->text('body');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('posts');
    }
}

Add the following code in the app/Models/Post.php file:

Read also: Laravel 8.0 Resource Routing Example
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    use HasFactory;

    protected $fillable = [
      'title',
      'body'
    ];
}

Migrate Database

php artisan migrate

Add Test Data

This step defines how to generate dummy data using the factory. This data loads dynamically on page scroll when testing the application.

php artisan make:factory PostFactory --model=Post
Read also: Laravel 8.0 Socialite Login with Google Account Example

Further, add the below code in database\factories\PostFactory.php:

<?php

namespace Database\Factories;

use App\Models\Post;
use Illuminate\Database\Eloquent\Factories\Factory;

class PostFactory extends Factory
{
    /**
     * The name of the factory's corresponding model.
     *
     * @var string
     */
    protected $model = Post::class;

    /**
     * Define the model's default state.
     *
     * @return array
     */
    public function definition()
    {
        return [
            'title' => $this->faker->name,
            'body' => $this->faker->text
        ];
    }
}

To generate the test data, Open the terminal and execute the below commands:

php artisan tinker
Post::factory()->count(200)->create()

Now, Create a Controller

php artisan:make controller PostController

Further, add the following code in the app/Http/Controllers/PostController.php file:

<?php
 namespace App\Http\Controllers;
 use Illuminate\Http\Request;
 use App\Models\Post; 
 use Validator;
 use Redirect;
 use Response;
 class PostController extends Controller
 {
     public function getArticles(Request $request)
     {
         $results = Post::orderBy('id')->paginate(10);
         $artilces = '';
         if ($request->ajax()) {
             foreach ($results as $result) {
                 $artilces.='
 '.$result->id.' '.$result->title.' '.$result->body.'
';
             }
             return $artilces;
         }
         return view('welcome');
     }    
 }

Create Route

go to routes/web.php file

<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\PostController;

Route::get('/posts', [PostController::class, 'getArticles']);

Set up Blade View Template

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">

<head>
    <meta name="csrf-token" content="{{ csrf_token() }}">

    <title>Laravel dynamic auto load more page scroll examle</title>

    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css">
</head>

<body>
<div class="container mt-5" style="max-width: 550px">
    <div id="data-wrapper">
        <!-- Results -->
    </div>

    <!-- Data Loader -->
    <div class="auto-load text-center">
        <svg version="1.1" id="L9" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
             x="0px" y="0px" height="60" viewBox="0 0 100 100" enable-background="new 0 0 0 0" xml:space="preserve">
                <path fill="#000"
                      d="M73,50c0-12.7-10.3-23-23-23S27,37.3,27,50 M30.9,50c0-10.5,8.5-19.1,19.1-19.1S69.1,39.5,69.1,50">
                    <animateTransform attributeName="transform" attributeType="XML" type="rotate" dur="1s"
                                      from="0 50 50" to="360 50 50" repeatCount="indefinite" />
                </path>
            </svg>
    </div>
</div>


<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
    var ENDPOINT = "{{ url('/') }}";
    var page = 1;
    infinteLoadMore(page);

    $(window).scroll(function () {
        if ($(window).scrollTop() + $(window).height() >= $(document).height()) {
            page++;
            infinteLoadMore(page);
        }
    });

    function infinteLoadMore(page) {
        $.ajax({
            url: ENDPOINT + "/posts?page=" + page,
            datatype: "html",
            type: "get",
            beforeSend: function () {
                $('.auto-load').show();
            }
        })
            .done(function (response) {
                if (response.length == 0) {
                    $('.auto-load').html("We don't have more data to display :(");
                    return;
                }
                $('.auto-load').hide();
                $("#data-wrapper").append(response);
            })
            .fail(function (jqXHR, ajaxOptions, thrownError) {
                console.log('Server error occured');
            });
    }

</script>
</body>

</html>

Start server and Run Project

php artisan serve

Go to browser and enter the below URL

http://127.0.0.1:8000/posts

Hope it helps you