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:
- Laravel 11 installed.
- Basic understanding of Laravel and jQuery.
- 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.
- Check our tools small Tools
- Check our tools website Word count