Laravel 11 JQuery Load More Data on Scroll
Laravel 11 JQuery Load More Data on Scroll

Laravel 11: Load More Data on Scroll Using jQuery

Loading more data on scroll is a common feature in modern web applications, enhancing user experience by dynamically loading content as the user scrolls down the page. In this article, we’ll explore how to implement this functionality using Laravel 11 and jQuery.

Prerequisites

Before we start, ensure you have the following:

  1. Laravel 11 installed.
  2. Basic understanding of Laravel and jQuery.
  3. A database set up with some data to load.

Step-by-Step Guide

1. Set Up Laravel Project

First, create a new Laravel project if you don’t have one already.

composer create-project --prefer-dist laravel/laravel load-more-demo
cd load-more-demo

2. Create a Model and Migration

We’ll create a model and migration for our data. For this example, let’s assume we’re loading Post data.

php artisan make:model Post -m

This command creates a Post model and a migration file. Open the migration file and define the schema for the posts table:

// database/migrations/xxxx_xx_xx_create_posts_table.php

public function up()
{
    Schema::create('posts', function (Blueprint $table) {
        $table->id();
        $table->string('title');
        $table->text('content');
        $table->timestamps();
    });
}

Run the migration to create the table:

php artisan migrate

3. Seed the Database

To see the functionality in action, let’s seed the database with some dummy data. Create a seeder:

php artisan make:seeder PostSeeder

Edit the seeder to generate some sample posts:

// database/seeders/PostSeeder.php

use Illuminate\Database\Seeder;
use App\Models\Post;

class PostSeeder extends Seeder
{
    public function run()
    {
        Post::factory()->count(100)->create();
    }
}

Don’t forget to create a factory for the Post model if it doesn’t already exist:

// database/factories/PostFactory.php

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

class PostFactory extends Factory
{
    protected $model = Post::class;

    public function definition()
    {
        return [
            'title' => $this->faker->sentence,
            'content' => $this->faker->paragraph,
        ];
    }
}

Now, seed the database:

php artisan db:seed --class=PostSeeder

4. Set Up Routes and Controller

Create a route to handle loading posts:

// routes/web.php

use App\Http\Controllers\PostController;

Route::get('/', [PostController::class, 'index']);
Route::get('/load-more', [PostController::class, 'loadMore'])->name('posts.load-more');

Create the PostController:

php artisan make:controller PostController

In the controller, define the index and loadMore methods:

// app/Http/Controllers/PostController.php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Post;

class PostController extends Controller
{
    public function index()
    {
        return view('posts.index');
    }

    public function loadMore(Request request)
    {
        $posts = Post::paginate(10); // Load 10 posts per request
        return view('posts.load-more', compact('posts'))->render();
    }
}

5. Create Views

Create a view to display the posts and load more button:

<!-- resources/views/posts/index.blade.php -->

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Load More Demo</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.2/css/bootstrap.min.css">
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
    <div class="container mt-5">
        <h1>Posts</h1>
        <div id="post-container">
            <!-- Posts will be loaded here -->
        </div>
        <div id="load-more-container" class="text-center mt-4">
            <button id="load-more" class="btn btn-primary">Load More</button>
        </div>
    </div>

    <script>
        $(document).ready(function(){
            let page = 1;

            function loadMoreData(page) {
                $.ajax({
                    url: "{{ route('posts.load-more') }}?page=" + page,
                    type: "get",
                    beforeSend: function() {
                        $('#load-more').text('Loading...');
                    }
                })
                .done(function(data) {
                    if(data.html == ""){
                        $('#load-more').text('No more posts');
                        return;
                    }
                    $('#load-more').text('Load More');
                    $('#post-container').append(data.html);
                })
                .fail(function(jqXHR, ajaxOptions, thrownError) {
                    alert('Server not responding...');
                });
            }

            $('#load-more').click(function(){
                page++;
                loadMoreData(page);
            });
        });
    </script>
</body>
</html>

Create a partial view for the posts:

<!-- resources/views/posts/load-more.blade.php -->

@foreach($posts as $post)
    <div class="card mt-3">
        <div class="card-body">
            <h5 class="card-title">{{ $post->title }}</h5>
            <p class="card-text">{{ $post->content }}</p>
        </div>
    </div>
@endforeach

6. Implement Scroll Event

To load more data when the user scrolls down, we’ll modify the jQuery code slightly:

$(document).ready(function(){
    let page = 1;

    function loadMoreData(page) {
        $.ajax({
            url: "{{ route('posts.load-more') }}?page=" + page,
            type: "get",
            beforeSend: function() {
                $('#load-more').text('Loading...');
            }
        })
        .done(function(data) {
            if(data.html == ""){
                $('#load-more').text('No more posts');
                return;
            }
            $('#load-more').text('Load More');
            $('#post-container').append(data.html);
        })
        .fail(function(jqXHR, ajaxOptions, thrownError) {
            alert('Server not responding...');
        });
    }

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

Conclusion

With these steps, you have implemented a “Load More Data on Scroll” feature using Laravel 11 and jQuery. This technique improves user experience by loading data dynamically as they interact with your application. You can customize the number of posts loaded per request or add additional features like loading spinners or error handling as needed.