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