article

Wednesday, May 3, 2023

Laravel 10 Infinite Scrolling

Laravel 10 Infinite Scrolling

Download Laravel App

composer create-project --prefer-dist laravel/laravel my-app
C:\xampp\htdocs\laravel10project>composer create-project laravel/laravel laravel10project

Connecting our Database

open .env file root directory.

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

Creating the Database and Model
php artisan make:migration create_posts_table --create=posts
C:\xampp\htdocs\laravel\laravel10project>php artisan make:migration create_posts_table --create=posts
database/migrations/create_posts_table.php

//database/migrations/create_posts_table.php
<?php

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

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

    public function down(): void
    {
        Schema::dropIfExists('posts');
    }
};
Database Migration
C:\xampp\htdocs\laravel\laravel10project>php artisan migrate

generate a model for the posts table

C:\xampp\htdocs\laravel\laravel10project>php artisan make:model Post

Generating Seed Data

Post model factory
php artisan make:factory PostFactory --model=Post
C:\xampp\htdocs\laravel\laravel10project>php artisan make:factory PostFactory --model=Post

Open the newly created factory in the database/factories/PostFactory.php
//database/factories/PostFactory.php
<?php

namespace Database\Factories;

use Illuminate\Database\Eloquent\Factories\Factory;

/**
 * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Post>
 */
class PostFactory extends Factory
{
    /**
     * Define the model's default state.
     *
     * @return array<string, mixed>
     */
    public function definition(): array
    {
        return [
            'title' => $this->faker->sentence,
            'content' => $this->faker->paragraphs(3, true),
        ];
    }
}
create a seeder to insert data
C:\xampp\htdocs\laravel\laravel10project>php artisan make:seeder PostsTableSeeder
database/seeders/PostsTableSeeder.php
//database/seeders/PostsTableSeeder.php
<?php

namespace Database\Seeders;

use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use App\Models\Post;

class PostsTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     */
    public function run(): void
    {
        Post::factory(100)->create();
    }
}
update the DatabaseSeeder database/seeders/DatabaseSeeder.php
//database/seeders/DatabaseSeeder.php
<?php

namespace Database\Seeders;

// use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     */
    public function run(): void
    {
        // \App\Models\User::factory(10)->create();

        // \App\Models\User::factory()->create([
        //     'name' => 'Test User',
        //     'email' => 'test@example.com',
        // ]);
        $this->call(PostsTableSeeder::class);
    }
}
seed the database
C:\xampp\htdocs\laravel\laravel10project>php artisan db:seed
Create Controller

php artisan make:controller PostController
C:\xampp\htdocs\laravel\laravel10project>php artisan make:controller PostController
app\Http\Controllers\PostController.php
//app\Http\Controllers\PostController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Response;
use App\Models\Post;

class PostController extends Controller
{
    public function index(Request $request)
    {
        $posts = Post::latest()->paginate(10);
        if ($request->ajax()) {
            $view = view('posts.load', compact('posts'))->render();
            return Response::json(['view' => $view, 'nextPageUrl' => $posts->nextPageUrl()]);
        }
        return view('posts.index', compact('posts'));
    }
}
Creating the Blade View
resources/views/posts/index.blade.php
//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>Laravel 10 Infinite Scrolling</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css">
    <script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"></script>
</head>
<body>
    <div class="container mt-5">
        <h2 class="mb-4">Posts</h2>
        <div id="posts-container">
            @include('posts.load')
        </div>
    </div>
<script>
$(document).ready(function () {
    let nextPageUrl = '{{ $posts->nextPageUrl() }}';
    $(window).scroll(function () {
        if ($(window).scrollTop() + $(window).height() >= $(document).height() - 100) {
            if (nextPageUrl) {
                loadMorePosts();
            }
        }
    });
    function loadMorePosts() {
        $.ajax({
            url: nextPageUrl,
            type: 'get',
            beforeSend: function () {
                nextPageUrl = '';
            },
            success: function (data) {
                nextPageUrl = data.nextPageUrl;
                $('#posts-container').append(data.view);
            },
            error: function (xhr, status, error) {
                console.error("Error loading more posts:", error);
            }
        });
    }
});
</script>
</body>
</html>
resources/views/posts/load.blade.php
//resources/views/posts/load.blade.php
@foreach($posts as $post)
    <div class="card mb-4">
        <div class="card-header">
            {{ $post->id }} : {{ $post->title }}
        </div>
        <div class="card-body">
            <p>{{ $post->content }}</p>
        </div>
    </div>
@endforeach

<div class="d-none">
    {{ $posts->links() }}
</div>
Routes
routes/web.php
//routes/web.php
<?php

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

Route::get('/', function () {
    return view('welcome');
});

Route::get('posts', [PostController::class, 'index']);
Run C:\xampp\htdocs\laravel\laravel10project>php artisan serve
Starting Laravel development server: http://127.0.0.1:8000

Related Post