Responsive Datatables Laravel Server Side

Posted on

Make Responsive Datatables Laravel Server-Side

When working with large datasets in web applications, creating responsive and efficient tables can be challenging. Laravel, paired with DataTables, offers a powerful solution for implementing server-side data processing. This article will guide you through setting up a responsive server side DataTables Laravel application using a simple example.

Datatables Laravel Responsive Server Side
Responsive Datatables Server Side using Laravel

Setting Up the Laravel Application

Install Laravel

Let’s start with a Laravel project installation as an example:

composer create-project laravel/laravel example-datatables-responsive
cd example-datatables-responsive

.env File

setting up a new Laravel project and configuring your database in the .env file:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=datatables_responsive_server_side
DB_USERNAME=root
DB_PASSWORD=

Run the necessary migrations to create the employees table and seed it with dummy data using Faker. Below is the migration and seeder code for the employees table:

Migration

Create a migration file. For example, we want to make the class CreateEmployeesTables, using the command:

php artisan make:migration create_employees_table

Now, open the file and fill it with the following format:

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateEmployeesTable extends Migration
{
    public function up(): void
    {
        Schema::create('employees', function (Blueprint $table) {
            $table->id();
            $table->string('first_name');
            $table->string('last_name');
            $table->string('position');
            $table->string('office');
            $table->integer('age');
            $table->date('start_date');
            $table->decimal('salary', 10, 2);
            $table->string('extn');
            $table->string('email');
            $table->timestamps();
        });
    }
    
    public function down(): void
    {
        Schema::dropIfExists('employees');
    }
}

Seeder

We will create a dummy data of 1000 rows, let’s create a seeder file first with the command:

php artisan make:seeder EmployeesTableSeeder

After that, in the seeder file, enter the following line of code:

use Illuminate\Database\Seeder;
use Faker\Factory as Faker;

class EmployeesTableSeeder extends Seeder
{
    public function run(): void
    {
        $faker = Faker::create();

        for ($i = 0; $i < 1000; $i++) {
            DB::table('employees')->insert([
                'first_name' => $faker->firstName,
                'last_name' => $faker->lastName,
                'position' => $faker->jobTitle,
                'office' => $faker->city,
                'age' => $faker->numberBetween(20, 65),
                'start_date' => $faker->date,
                'salary' => $faker->numberBetween(30000, 100000),
                'extn' => $faker->numberBetween(1000, 9999),
                'email' => $faker->email,
            ]);
        }
    }
}

Run the migration and seeder with the following commands:

php artisan migrate
php artisan db:seed --class=EmployeesTableSeeder

Model

Create a model file first with the following command:

php artisan make:model Employee

then in the model file:

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Employee extends Model
{
    use HasFactory;

    protected $table = 'employees';

    protected $fillable = [
        'first_name',
        'last_name',
        'position',
        'office',
        'age',
        'start_date',
        'salary',
        'extn',
        'email',
    ];
}

Controller

Next, create a controller named EmployeeController to handle the server-side processing for the DataTable:

php artisan make:controller EmployeeController

Inside the controller:

namespace App\Http\Controllers;

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

class EmployeeController extends Controller
{
    public function index()
    {
        return view('welcome');
    }

    public function getEmployees(Request $request)
    {
        $columns = ['first_name', 'last_name', 'position', 'office', 'age', 'start_date', 'salary', 'extn', 'email'];

        $query = Employee::query();

        // Search functionality
        if ($request->has('search') && $request->search['value']) {
            $searchValue = $request->search['value'];
            $query->where(function ($q) use ($searchValue, $columns) {
                foreach ($columns as $column) {
                    $q->orWhere($column, 'LIKE', "%$searchValue%");
                }
            });
        }

        $totalRecords = $query->count();

        // Sorting functionality
        if ($request->has('order')) {
            $orderColumn = $columns[$request->order[0]['column']];
            $orderDirection = $request->order[0]['dir'];
            $query->orderBy($orderColumn, $orderDirection);
        }

        // Pagination functionality
        $data = $query->offset($request->start)
            ->limit($request->length)
            ->get();

        return response()->json([
            'draw' => $request->draw,
            'recordsTotal' => $totalRecords,
            'recordsFiltered' => $totalRecords,
            'data' => $data
        ]);
    }
}

Setting Up the Frontend

For the view, use DataTables with Bootstrap to create a responsive table. Include the necessary CSS and JS files. Using this code in your welcome.blade.php file:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>DataTables Example</title>
    <!-- Bootstrap CSS -->
    <link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/5.3.0/css/bootstrap.min.css" rel="stylesheet">
    <!-- DataTables CSS -->
    <link href="https://cdn.datatables.net/2.1.4/css/dataTables.bootstrap5.css" rel="stylesheet">
    <link href="https://cdn.datatables.net/responsive/3.0.2/css/responsive.bootstrap5.css" rel="stylesheet">
</head>
<body>
    <div class="container mt-5">
        <table id="example" class="table table-striped nowrap" style="width:100%">
            <thead>
                <tr>
                    <th>First name</th>
                    <th>Last name</th>
                    <th>Position</th>
                    <th>Office</th>
                    <th>Age</th>
                    <th>Start date</th>
                    <th>Salary</th>
                    <th>Extn.</th>
                    <th>E-mail</th>
                </tr>
            </thead>
        </table>
    </div>

    <!-- jQuery -->
    <script src="https://code.jquery.com/jquery-3.7.1.js"></script>
    <!-- Bootstrap JS -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/5.3.0/js/bootstrap.bundle.min.js"></script>
    <!-- DataTables JS -->
    <script src="https://cdn.datatables.net/2.1.4/js/dataTables.js"></script>
    <script src="https://cdn.datatables.net/2.1.4/js/dataTables.bootstrap5.js"></script>
    <script src="https://cdn.datatables.net/responsive/3.0.2/js/dataTables.responsive.js"></script>
    <script src="https://cdn.datatables.net/responsive/3.0.2/js/responsive.bootstrap5.js"></script>
    <script>
        $(document).ready(function() {
            $('#example').DataTable({
                responsive: true,
                processing: true,
                serverSide: true,
                ajax: '{{ url('/data') }}',
                columns: [
                    { data: 'first_name', name: 'first_name' },
                    { data: 'last_name', name: 'last_name' },
                    { data: 'position', name: 'position' },
                    { data: 'office', name: 'office' },
                    { data: 'age', name: 'age' },
                    { data: 'start_date', name: 'start_date' },
                    { data: 'salary', name: 'salary' },
                    { data: 'extn', name: 'extn' },
                    { data: 'email', name: 'email' }
                ]
            });
        });
    </script>
</body>
</html>

Defining Routes

Finally, define the routes in your web.php file:

use App\Http\Controllers\EmployeeController;

Route::get('/', [EmployeeController::class, 'index']);
Route::get('/data', [EmployeeController::class, 'getEmployees']);

By integrating DataTables with Laravel, you can efficiently manage large datasets in a responsive table format. This setup includes server-side processing for sorting, searching, and pagination, making your application scalable and user-friendly. The steps outlined above provide a solid foundation for implementing DataTables in your Laravel projects.