March 23, 2021 · 5 min read · 10,384 views
Update Notice:
We've corrected the code for generating the Single Action Controller, as well as a clarification. As noted at the outset of the article, we're operating under the assumption that you have a Laravel project up and running. To keep this tutorial concise, we've omitted the initial steps of scaffolding a new Laravel project and seeding the database. Regarding the final design showcased in the screenshot, it's crafted using Tabler, a free and versatile dashboard template compatible with Bootstrap 5. While this article doesn't delve into styling details (since our focus here is functionality), it's worth mentioning that Grid.js offers extensive customization options, as detailed in their docs.
In the realm of web development, presenting users with large datasets can be daunting. With Bootstrap's move away from jQuery, developers can no longer rely on the widely-used DataTables plugin for managing voluminous data displays. This shift has prompted developers to seek alternative solutions. At Lucky Media, we pride ourselves on delivering bespoke design solutions tailored with TailwindCSS, which led us to explore vanilla JavaScript options that could be adapted to our exacting standards.
Our exploration led us to Grid.js, a powerful, free, and open-source JavaScript plugin designed for creating tables. What makes Grid.js particularly appealing is its compatibility across a wide array of JavaScript frameworks, such as React, Angular, Vue, and even VanillaJs. In this tutorial, we'll walk you through the process of integrating Grid.js with server-side rendering in a Laravel 8 project.
Please note: This tutorial presumes the existence of a Laravel 8 project on your development environment. Should you require assistance in setting up your project, we invite you to explore our Laravel development services for expert guidance.
Note: This tutorial presumes the existence of a Laravel 8 project on your development environment. Should you require assistance in setting up your project, we invite you to explore our Laravel development services for expert guidance.
npm install gridjs
To begin, we'll install Grid.js in our project. We have a Clients model with more than 100 records, and we'll use Grid.js to display all this data on the frontend. You can also use a seeder for this purpose.
First, we'll create a single action controller that fetches all the clients and returns a JSON response that we can use on the frontend. To create the invokable controller, use the following command:
php artisan make:controller Actions\\FetchClientsController --invokable
This command stores our new invokable controller in an Actions folder, helping to keep our controllers clean and organized.
Here's what our FetchClientController
looks like:
<?php
namespace App\Http\Controllers\Actions;
use App\Http\Controllers\Controller;
use \Illuminate\Http\JsonResponse;
use App\Models\Client;
class FetchClientsController extends Controller
{
public function __invoke(): JsonResponse
{
$clients = Client::all()
->transform(function($client){
return [
'id' => $client->id,
'full_name' => "$client->name $client->surname",
'number' => $client->number,
'street' => $client->street,
'edit_url' => route('clients.edit', $client->id)
];
});
return response()->json($clients);
}
}
Here on the controller we get all our Clients, and then using the transform function we only return the needed fields in the frontend. Note the last line for edit_url
, we will use it to automatically get the url for editing data so we can use it in the table.
We navigate to the routes folder and we access web.php
file to reference our new controller like so:
<?php
use Illuminate\Support\Facades\Route;
use \App\Http\Controllers\ClientController;
use \App\Http\Controllers\Actions\FetchClientsController;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Auth::routes();
Route::group(['middleware' => 'auth'], function () {
// Single Action Controllers
Route::get('/clients/fetch', FetchClientsController::class)->name('clients.fetch');
// Resource Controllers
Route::resource('clients', ClientController::class);
});
Now, all we have to do is configure our index file in order to render our table from JavaScript.
In our resource/views/clients/index.blade.php
we have the following code:
@extends('layouts.app', ['title' => 'Clients'])
@section('content')
<div class="row">
<div class="col-lg-12">
<div js-hook-url="{{ route('clients.fetch') }}" js-hook-table-client></div>
</div>
</div>
@endsection
In this example we use two HTML attributes that we will use in our JavaScript file, the first one is for retrieving our URL where we fetch all the clients, and we are going to use the second one as a reference to render our table from JavaScript.
In our app.js
file under resources/js/app.js
we need to add the following code.
import { Grid, html } from "gridjs";
import "gridjs/dist/theme/mermaid.css";
const TABLE_CLIENTS = '[js-hook-table-client]'
// Get the table element
const table_clients_wrapper = document.querySelector(TABLE_CLIENTS);
// Get the url attribute
const table_clients_url = table_clients_wrapper.getAttribute('js-hook-url');
if (table_clients_wrapper) {
const table_clients = new Grid({
columns: [
{
name: 'Full Name'
},
{
name: 'Number'
},
{
name: 'Street'
},
{
name: 'Actions',
// Here we inject our route edit
formatter: (_, row) => html(`<a href='${row.cells[3].data}'>Edit</a>`)
}
],
search: {
enabled: true
},
server: {
// Here we give the URL we passed in the hook
url: table_clients_url,
then: data => data.map(table => [table.full_name, table.number, table.street, table.edit_url]),
handle: (res) => {
// no matching records found
if (res.status === 404) return {data: []};
if (res.ok) return res.json();
throw Error('oh no :(');
},
},
pagination: {
enabled: true,
limit: 10,
summary: false
},
}).render(table_clients_wrapper);
}
So, what are we doing here? We instantiate a new Grid Class and pass down the options as objects. The columns array represents all the table columns, and the last item is used to inject our edit route. In the server object, we give the URL parameter that we called earlier, and after the data has been loaded, we just map each data that's coming from the server with their respective columns.
The pagination part is self-explanatory. We have enabled pagination and set the limit of rows to be displayed at 10.
You can read more about this in the official Grid.JS documentation which covers a lot of use cases.
After this, you have to run npm run dev
in order to compile all the assets. If you did everything correctly then you should see the following screen:
Tip: You can use the following library to cache your models and supercharge your loading times. We highly recommend it for large data: laravel-model-caching.
If you need help with a Laravel project let's get in touch.
Lucky Media is proud to be recognized as a Top Laravel Development Agency
Technologies:
Related Posts
Stay up to date
Be updated with all news, products and tips we share!