In this tutorial we’ll embed datatable functionality in a Laravel 9 VILT app using Ant Design Vue Table component. To achieve full optimization, sorting and pagination will be done at client-side while searching will be routed to server-side through Inertia.js in order to always have updated data.
Laravel 9.x requires a minimum PHP version of 8.0. This tutorial assumes that you are using Linux, macOS or WSL on Windows and Node.js, Composer and PHP 8 along with required modules i.e bcmatch, sqlite, mbstring, xml, zip, gd, mcrypt are properly installed. Also make sure that SQLite is installed as we’ll be using SQLite to keep things simple and quick; you may use MySQL or PostgreSQL as you like, however make sure the corresponding PHP module is installed too.
Using Composer, enter following command in terminal to install Laravel 9;
composer create-project laravel/laravel app 9.*
Go inside newly created app folder by executing;
cd app
Now, add Breeze package by executing following command;
composer require laravel/breeze:* --dev
Then install Breeze with Vue and Inertia.js functionality by executing following command;
php artisan breeze:install vue
Next, setup database and Laravel environment file. Here, I’m configuring SQLite database for simplicity purposes.
Being in parent folder (app), execute following command in order to create new SQLite database file;
touch database/database.sqlite
Then find .env config file in the parent folder, open it and amend DB_CONNECTION line as follows;
DB_CONNECTION = sqlite
Remove or comment out DB_HOST, DB_PORT, DB_DATABASE, DB_USERNAME, DB_PASSWORD lines from .env as we are using local SQLite database file.
Now enter following command in order to run the migrations:
php artisan migrate
In order to populate database quickly, let’s utilize User model and its factory which are installed by default. So, enter following command to invoke tinker;
php artisan tinker
And then enter following command to add 100 randomly generated users in database;
User::factory(100)->create()
Type ‘quit’ and press Enter to exit tinker.
Since we are done with the initial setup of Laravel 9 VILT app and also set up the database for testing purposes, let’s move towards incorporating Ant Design Vue Table component. First, install node module ant-design-vue by executing following command in parent (app) folder:
npm install ant-design-vue --save
Then, create a new folder Users by entering following command in parent folder:
mkdir resources/js/Pages/Users
Now, create Index.vue inside this folder by entering following command:
touch resources/js/Pages/Users/Index.vue
Then, insert following code inside Index.vue:
<template>
<div class="min-h-screen flex flex-col sm:justify-center items-center pt-6 sm:pt-0 bg-gray-100">
<div class="md:w-3/4 sm:w-auto m-6 px-6 py-4 bg-white shadow-md overflow-hidden sm:rounded-lg">
<Select
v-model:value="select"
style="width: 120px"
:options="options"
/>
<InputSearch
v-model:value="search"
placeholder="input search text"
style="width: 200px"
@search="onSearch"
/>
<Table
:columns="columns"
:data-source="users"
:loading="loading"
class="mt-2"
size="small"
>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'actions'">
<a href="/users">
{{ record.name }}
</a>
</template>
</template>
</Table>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { router } from '@inertiajs/vue3'
import { Table, Select, InputSearch } from 'ant-design-vue'
import 'ant-design-vue/dist/antd.css'
const props = defineProps({
users : Object,
})
const select = ref('name')
const search = ref('')
const columns = [{
title: 'ID',
dataIndex: 'id',
sorter: (a, b) => a.id - b.id,
width: '10%',
},
{
title: 'Name',
dataIndex: 'name',
sorter: (a, b) => {
const nameA = a.name.toUpperCase();
const nameB = b.name.toUpperCase();
if (nameA < nameB) {
return -1;
}
if (nameA > nameB) {
return 1;
}
return 0;
},
width: '20%',
},
{
title: 'Email',
dataIndex: 'email',
},
{
title: 'Actions',
dataIndex: 'actions',
key: 'actions',
}]
const options = [{
value: 'name',
label: 'Name',
}, {
value: 'email',
label: 'Email',
}]
const onSearch = searchValue => {
router.get(route('users'), {select:select.value,search:search.value}, {replace:true, preserveState:true});
}
</script>
Finally, insert following new route inside routes/web.php:
Route::get('/users', function (Illuminate\Http\Request $request) {
$users = null;
if(request()->has(['select','search'])){
$users = App\Models\User::where($request->select,'like', '%'.$request->search.'%')->get();
}
else{
$users = App\Models\User::all();
}
return Inertia::render('Users/Index', ['users'=>$users]);
})->name('users');
Compile UI assets by entering following command:
npm run build
Run development server by running:
php artisan serv
Then, enter following URL in the browser:
localhost:8000/users
Voilà! you have fully functional datatable with capabilities of client-side sorting and pagination along with server-side Ajax searching.