Laravel – Filter & Pagination Data with AJAX
I assume you already have a code to show your list of data with pagination and filter/search by field condition feature. In this case i want the ‘pagination’ feature work with no need to refresh the page when I click on the others page. For example when I click page 4, it will not refresh the page but only change the data on the table.
Step 1 – Make a condition for Ajax Request on the Controller
public function index(Request $request) { $keyword = $request->get('search'); $datas = \App\YourModel::where('name', 'LIKE', '%' . $keyword . '%') ->paginate(); if ($request->ajax()) { return \Response::json(\View::make('list', array('datas' => $datas))->render()); } return view('index',compact('datas', 'keyword')); }
when there’s an ajax request, it will just render a view from “list.blade.php” on the view. It will bring the $datas value.
Step 2 – Create list.blade.php file for it view
<div id="load" class="table-responsive"> <table class="table m-b-0"> <thead> <tr> <th>Name</th> <th colspan="2">Action</th> </tr> </thead> <tbody> @foreach($datas as $data) <tr> <td>{{$data['nama']}}</td> <td><a href="{{action('YourController@edit', $data['id'])}}" class="btn btn-warning">Edit</a></td> <td> <form action="{{action('YourController@destroy', $data['id'])}}" method="post"> @csrf <input name="_method" type="hidden" value="DELETE"> <button class="btn btn-danger" type="submit">Delete</button> </form> </td> </tr> @endforeach </tbody> </table> {{ $datas->links() }} </div>
Step 3 – We already have list.blade.php file, we can use it on index.blade.php
@section('content') <div class="container"> <br /> @if (\Session::has('success')) <div class="alert alert-success"> <p>{{ \Session::get('success') }}</p> </div><br /> @endif <div class="card"> <div class="body"> <form action="{{url('yourpath')}}" method="get"> <div class="input-group mb-3"> @csrf <input type="text" class="form-control" name="search" id="search" value="{{ $keyword }}" placeholder="Search.."> <div class="input-group-append"> <button class="btn btn-info" type="submit"><i class="fa fa-search"></i></button> </div> </div> </form> <section class="datas"> @include('list') </section> </div> </div> </div> @endsection
under section class=”data” we include a list.blade.php file to render. So no need to define the view twice. On that file we have a search form too, we will use it for filter our data depend on that form (see on the controller, we already have a code to filter data depend on “search” form)
Step 4 – Create a JS code to handle Ajax Request
The code we create before already work for pagination & filter, but it not using Ajax. For handle ajax request, insert this js code on the view.
$(window).on('hashchange', function() { if (window.location.hash) { var page = window.location.hash.replace('#', ''); if (page == Number.NaN || page <= 0) { return false; } else { getDatas(page); } } }); $(document).ready(function() { $(document).on('click', '.pagination a', function (e) { $('.datas').append('<img style="position: absolute; left: 0; top: 0; z-index: 100000;" src="../public/images/loading.gif" />'); var url = $(this).attr('href'); getDatas($(this).attr('href').split('page=')[1]); e.preventDefault(); }); }); function getDatas(page) { $.ajax({ url : '?page=' + page, type : "get", dataType: 'json', data:{ search: $('#search').val() }, }).done(function (data) { $('.datas').html(data); location.hash = page; }).fail(function (msg) { alert('Gagal menampilkan data, silahkan refresh halaman.'); }); }
Step 5 – Fixing bugs on pagination
There’s a condition where the path for pagination different with current path. We need to set the path on the controller code like this:
$datas->withPath('yourPath');
another problem is laravel pagination not take the filter field request on it pagination. For example we have been filter the data by name, when we try to go to another page it not showing the data from the filter condition before. We can fix it by add this code on the controller.
$datas->appends($request->all());
So the final data for controller will be like this:
public function index(Request $request) { $keyword = $request->get('search'); $datas = \App\YourModel::where('name', 'LIKE', '%' . $keyword . '%') ->paginate(); $datas->withPath('yourPath'); $datas->appends($request->all()); if ($request->ajax()) { return \Response::json(\View::make('list', array('datas' => $datas))->render()); } return view('index',compact('datas', 'keyword')); }
That’s all.. happy coding..