Data Table Pagination with Live Search using Laravel, jQuery, and Ajax Request
In this tutorial, you can learn to create a Live Search Box feature in Laravel 10 Data with Pagination. The tutorial aims to provide students and beginners with a reference for learning to create a useful feature or component of a Laravel Project. Here, I will be providing a simple web application script that demonstrates the creation of the said feature using the Laravel version 10 Framework.
What is Live Search Box?
A Live Search Box is one of the often implemented features or web features in websites or web applications. This is usually used to easily filter the specific data that matches the entered keyword on the search box input. This feature works dynamically without leaving the current page or reloading the pages which means that the new data will be automatically updated without reloading the page assets and other elements.
How to Create a Live Search Box?
There are plenty of ways to achieve the Live Search Box for the paginated data in Laravel Projects. Most of these ways are through HTTP Request. Using jQuery's Ajax Request we can achieve this kind of feature or component. We can simply initiate the Request through Ajax when there are changes made to the search box input. After the Ajax Request has been fulfilled, we can update the data with the updated ones. Check out the source code scripts I have provided below to understand it more.
Sample Scripts
The scripts below are the modified file script of my previously published Laravel Project which is the "Laravel 10: Paginate DB Table Data with Bootstrap Tutorial". Kindly click the provided link (my previously published tutorial title) if you want to learn from scratch.
The modified script result in a simple Laravel Project web page that contains a table that displays the list of members data from the database with the Pagination Feature. Using the scripts, the project will have a search box input on the front end and when the user updates the search input value, the search process will be executed and updates the table data with the members data that contains information that matches the given keyword. Here, the live search feature has the ability to preserve the searched keyword whereas the entered keyword will stay on the search input field and the searched data will remain even if the user forcibly reloads or refresh the page.
Page View File Script
The modified file is known as members.blade.php. It is a PHP file that contains the HTML and PHP codes for the elements and displays the retrieved data. This file is located in the resources/views directory of the project.
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <!-- Bootstrap CDN Link -->
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css">
- <!-- Fontawesome CDN Link -->
- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" integrity="sha512-iecdLmaskl7CVkqkXNQ/ZH/XLlvWZOJyj7Yy7tcenmpD1ypASozpmT/E0iPtmFIB46ZmdtAc9eNBvH0H/ZpiBw==" crossorigin="anonymous" referrerpolicy="no-referrer" />
- <!-- jQuery CDN JS -->
- <!-- Bootstrap CDN JS -->
- <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
- <!-- Fontawesome CDN JS -->
- </head>
- <body>
- <div class="container-md py-5">
- <div class="col-lg-5 col-md-6 col-sm-12 col-12 mx-auto my-2">
- <!-- Search Box -->
- <div class="input-group">
- <input type="search" class="form-control rounded-0" id="search" placeholder="Search here..." value="{{$kw}}">
- </div>
- <!-- Search Box -->
- </div>
- <div class="table-responsive">
- <!-- Data Table -->
- <table id="membersTbl" class="table table-sm table-bordered table-striped">
- <thead>
- <tr>
- </tr>
- </thead>
- <tbody>
- @foreach($members as $member)
- <tr>
- </tr>
- @endforeach
- @if(count($members) <= 0)
- <tr>
- @if(empty($kw))
- <!-- If No data to display -->
- @else
- <!-- If No Data match the keyword -->
- @endif
- </tr>
- @endif
- </tbody>
- </table>
- <!-- Data Table -->
- <!-- Pagination Link Wrapper -->
- <div id="pagination-links">
- {{$members->onEachSide(2)->links()}}
- </div>
- <!-- Pagination Link Wrapper -->
- </div>
- </div>
- </body>
- <script>
- // Ajax Variable
- var search_ajax;
- $(document).ready(function(){
- // Execute Live Searcing when search box input has character entered or change
- $('#search').on('input change', function(e){
- e.preventDefault()
- // current keyword value
- var searchTxt = $(this).val()
- // Get Url Parameters
- var urlParams = new URLSearchParams(location.search);
- // New Parameters aray
- var newParams = []
- urlParams.forEach((v, k) => {
- if(k == 'q'){
- // update keyword value
- v = searchTxt
- }
- // Add parameter to the new parameter
- if(searchTxt != "" && k == 'q')
- newParams.push(`${k}=${encodeURIComponent(v)}`);
- })
- // Update Location URL without reloading the page
- if(newParams.length > 0){
- // structuring the new URL
- var newLink = `{{URL::to('/')}}?`+(newParams.join('&'));
- // Update the location URL
- history.pushState({}, "", newLink)
- }else{
- if(searchTxt != ""){
- // Update location URL
- history.pushState({}, "", `{{URL::to('/')}}?q=${encodeURIComponent(searchTxt)}`)
- }else{
- // Update location URL
- history.pushState({}, "", `{{URL::to('/')}}`)
- }
- }
- if(search_ajax != undefined && search_ajax != null){
- // Abort Previous Search Ajax Process if exists
- search_ajax.abort();
- }
- // Start Search Ajax Process
- search_ajax = $.ajax({
- url:`{{URL::to('search')}}?q=${searchTxt}`,
- dataType:'json',
- error: err => {
- console.log(err)
- if(err.statusText != 'abort')
- alert('An error occurred');
- },
- success: function(resp){
- if(!!resp.members){
- // Data Table Body Element
- var tblBody = $('#membersTbl tbody')
- // Page Links Wrapper Element
- var paginationLink = $('#pagination-links')
- // remove current data on the table
- tblBody.html('')
- // remove current pagination links
- paginationLink.html('')
- if(!!resp.members.data){
- // Loop the searched data
- Object.values(resp.members.data).map(member => {
- // creating new table row
- var tr = $('<tr>')
- // creting the new columns and data of the row
- // inserting the created data row the table
- tblBody.append(tr)
- })
- if(Object.keys(resp.members.data).length <= 0){
- // Display Message if no data found that is match to the keyword
- var tr = $('<tr>')
- tblBody.append(tr)
- }
- }
- // Update Pagination link
- if(!!resp.members.pagination_links)
- paginationLink.html(resp.members.pagination_links)
- }
- }
- })
- })
- })
- </script>
- </html>
I used CDNs link for the sources of the Bootstrap, jQuery, and Fontwesome libraries or packages which means that an internet connection is a must when browsing the web page.
Controller
The PHP file script below is the modified file content of the membersController.php. It contains the modified script of the index method of the class for rendering the web page and the new method called search. The search method of this controller class is used for retrieving the search data that is executed through Ajax Request. This file can be found in the apps/Http/Controllers directory.
- <?php
- namespace App\Http\Controllers;
- use App\Models\Members;
- use Illuminate\Http\Request;
- class MembersController extends Controller
- {
- /**
- * Display a listing of the resource.
- */
- public function index(Request $request)
- {
- // search keyword
- $kw = $request->q;
- // Display All data with pagination if no keyword to search
- $members = Members::paginate(10);
- }else{
- // Display Filtered data with pagination if keyword exists
- $members = Members::where('name', 'like' , "%{$kw}%")
- ->orwhere('email', 'like' , "%{$kw}%")
- ->orwhere('phone', 'like' , "%{$kw}%")
- ->paginate(10)
- ->appends(['q'=> "{$kw}"])
- ->withPath('/')
- ->withQueryString();
- }
- // render page view
- return view('members', ['members'=>$members, 'kw' => $kw]);
- }
- /**
- * Ajax Live Search Listing of the resource
- */
- public function search(Request $request){
- // search keyword
- $kw = $request->q;
- // Display All data with pagination if no keyword to search
- $members = Members::paginate(10);
- }else{
- // Display Filtered data with pagination if keyword exists
- $members = Members::where('name', 'like' , "%{$kw}%")
- ->orwhere('email', 'like' , "%{$kw}%")
- ->orwhere('phone', 'like' , "%{$kw}%")
- ->paginate(10)
- ->appends(['q'=> "{$kw}"])
- ->withPath('/')
- ->withQueryString();
- }
- // converting array to laravel collection
- $membersCollection = collect($members);
- // merging queried data with pagination links HTML
- $membersCollection = $membersCollection->merge(['pagination_links' => (string) $members->onEachSide(2)->links()]);
- // returning the response data as JSON string
- return collect(["members" => $membersCollection->all()])->toJson();
- }
- /**
- * Show the form for creating a new resource.
- */
- public function create()
- {
- //
- }
- /**
- * Store a newly created resource in storage.
- */
- public function store(Request $request)
- {
- //
- }
- /**
- * Display the specified resource.
- */
- public function show(Members $members)
- {
- //
- }
- /**
- * Show the form for editing the specified resource.
- */
- public function edit(Members $members)
- {
- //
- }
- /**
- * Update the specified resource in storage.
- */
- public function update(Request $request, Members $members)
- {
- //
- }
- /**
- * Remove the specified resource from storage.
- */
- public function destroy(Members $members)
- {
- //
- }
- }
Routes
Finally, here's the last modified PHP file known as web.php. The file contains the routing script of the project for viewing the page content and retrieving data using Ajax Request. The file is located in the routes directory.
- <?php
- use Illuminate\Support\Facades\Route;
- use App\Http\Controllers\MembersController;
- /*
- |--------------------------------------------------------------------------
- | Web Routes
- |--------------------------------------------------------------------------
- |
- | Here is where you can register web routes for your application. These
- | routes are loaded by the RouteServiceProvider and all of them will
- | be assigned to the "web" middleware group. Make something great!
- |
- */
- // Route::get('/', function () {
- // return view('welcome');
- // });
- Route::controller(MembersController::class)->group(function(){
- Route::get('/', 'index');
- Route::get('/search', 'search');
- });
Snapshots
Here are some snapshots of the modified Laravel Project.
Page Interface
Sample Search Result #1
Sample Search Result #2
There you go! I also have provided the complete modified source code zip file of the sample Laravel Project on this website and it is free to download. The download button can be found below this tutorial's content. Feel free to download and modify the source code the way you wanted to enhance your programming capabilities using PHP and Laravel 10 Framework.
How to Run the source code?
- Please start the Apache and MySQL servers of your XAMPP or equivalent software.
- Extract the source code folder into the XAMPP's htdocs directory or equivalent directory.
- Create a new database named dummy_db
- Open the terminal or command prompt and redirect the directory to the source code folder
- Run the php artisan migrate command
- Run the php artisan make:seeder MembersSeeder command
- Run the php artisan serve command
- Browse the application. http://127.0.0.1:8000
That's it! I hope this Data Table Pagination with Live Search using Laravel, jQuery, and Ajax Request Tutorial will help you with what you are looking for and you'll find something useful for your current and future PHP or Laravel Projects.
Explore more on this website for more Tutorials and Free Source Codes.
Happy Coding =)
Add new comment
- 2343 views