Sunday, May 11, 2025

Pagination in Laravel with Ajax

Implementing pagination with Ajax in Laravel allows you to load paginated content without page refreshes. Here's a complete guide to implementing this feature:

Basic Setup

1. Controller Setup

First, set up your controller to return paginated data:

php
// app/Http/Controllers/PostController.php
namespace App\Http\Controllers;

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

class PostController extends Controller
{
    public function index()
    {
        $posts = Post::paginate(10); // 10 items per page
        return view('posts.index', compact('posts'));
    }
    
    public function fetch_data(Request $request)
    {
        if ($request->ajax()) {
            $posts = Post::paginate(10);
            return view('posts.pagination_data', compact('posts'))->render();
        }
    }
}

2. Create Views

Main view (resources/views/posts/index.blade.php):

html
@extends('layouts.app')

@section('content')
<div class="container">
    <h2>Posts</h2>
    <div id="post-data">
        @include('posts.pagination_data')
    </div>
</div>
@endsection

Pagination partial (resources/views/posts/pagination_data.blade.php):

html
<div class="posts">
    @foreach($posts as $post)
        <div class="post">
            <h3>{{ $post->title }}</h3>
            <p>{{ $post->body }}</p>
        </div>
    @endforeach
</div>

<div class="pagination">
    {{ $posts->links() }}
</div>

3. Routes

php
// routes/web.php
use App\Http\Controllers\PostController;

Route::get('/posts', [PostController::class, 'index']);
Route::post('/posts/fetch_data', [PostController::class, 'fetch_data'])->name('posts.fetch_data');

Ajax Implementation

Add jQuery/Ajax to handle pagination clicks:

javascript
// In your main view or a separate JS file
$(document).ready(function() {
    $(document).on('click', '.pagination a', function(e) {
        e.preventDefault();
        var page = $(this).attr('href').split('page=')[1];
        fetch_data(page);
    });
    
    function fetch_data(page) {
        $.ajax({
            url: "{{ route('posts.fetch_data') }}?page=" + page,
            success: function(data) {
                $('#post-data').html(data);
            }
        });
    }
});

Advanced Implementation with Filters

If you need filtering with pagination:

1. Update Controller

php
public function fetch_data(Request $request)
{
    if ($request->ajax()) {
        $sort_by = $request->get('sort_by', 'created_at');
        $sort_type = $request->get('sort_type', 'desc');
        
        $posts = Post::orderBy($sort_by, $sort_type)
                    ->paginate(10);
                    
        return view('posts.pagination_data', compact('posts'))->render();
    }
}

2. Update Ajax

javascript
function fetch_data(page, sort_by, sort_type) {
    $.ajax({
        url: "{{ route('posts.fetch_data') }}?page=" + page + 
             "&sort_by=" + sort_by + 
             "&sort_type=" + sort_type,
        success: function(data) {
            $('#post-data').html(data);
        }
    });
}

// Example of calling with sorting
$('#sort-title').on('click', function() {
    fetch_data(1, 'title', 'asc');
});

Loading Indicator

Add a loading indicator for better UX:

javascript
function fetch_data(page) {
    $('#post-data').html('<div class="text-center"><i class="fa fa-spinner fa-spin"></i> Loading...</div>');
    
    $.ajax({
        url: "{{ route('posts.fetch_data') }}?page=" + page,
        success: function(data) {
            $('#post-data').html(data);
        },
        error: function() {
            $('#post-data').html('<div class="alert alert-danger">Error loading data.</div>');
        }
    });
}

Using Laravel Resources (API-style)

For a more API-like approach:

php
// In controller
public function fetch_data(Request $request)
{
    $posts = Post::paginate(10);
    return response()->json([
        'html' => view('posts.pagination_data', compact('posts'))->render(),
        'next_page' => $posts->nextPageUrl()
    ]);
}
javascript
// In AJAX
$.ajax({
    url: "{{ route('posts.fetch_data') }}?page=" + page,
    dataType: 'json',
    success: function(response) {
        $('#post-data').html(response.html);
        // You can use response.next_page if needed
    }
});

This implementation provides a smooth, dynamic pagination experience without page reloads in our Laravel application.

No comments:

Post a Comment