Laratables
Ajax support of DataTables (Laravel 5.5 to Laravel 11.x)
Install / Use
/learn @freshbitsweb/LaratablesREADME
Package Status
This package is not under active development. We no longer plan to add new features. The main reason being that our company projects do not use Datatables anymore.
If you wish to maintain a fork of this package, I would be more than happy to link.
Laratables
A Laravel package to handle server side ajax of Datatables.
Table of contents
- Introduction
- How to use
- Demo Repositories
- Installation
- Customization
Introduction
This package helps with simple requirements of displaying data from eloquent models into datatables with ajax support. Plus, using simple relationships and customizing column values. Laratables does not work with Datatables Editor yet.
How to use
The basic approach is that you can specify the Datatable configuration and columns on the client side just like you would without any major change and call a single method on the server side to handle ajax calls. The package will create necessary queries to fetch the data and make the search and ordering functionality work automatically. If needed, You can step-in and customize query/data/logic at various stages by adding methods in your Eloquent model or a custom class.
Client side
$('#users-table').DataTable({
serverSide: true,
ajax: "{{ route('admin.users.datatables') }}",
columns: [
{ name: 'id' },
{ name: 'name' },
{ name: 'email' },
{ name: 'role.name', orderable: false },
{ name: 'action', orderable: false, searchable: false }
],
...
});
⚠️ IMP Note ⚠️ - The client side code decides the columns that should be fetched. If you are showing the table on a public facing page, malicious users can modify the HTTP request to fetch data for other columns of respective table and related tables. It is highly recommend that you validate the requests before returning the data.
Server side
use App\User;
use Freshbitsweb\Laratables\Laratables;
...
return Laratables::recordsOf(User::class);
There are multiple ways to customize query/data/logic. Check Customization section below for details.
Demo Repositories
- https://github.com/freshbitsweb/laratables-demo-one-to-many
- https://github.com/freshbitsweb/laratables-demo-customize-column
- https://github.com/freshbitsweb/laratables-demo-basic
- https://github.com/freshbitsweb/laratables-demo-many-to-many
- https://github.com/freshbitsweb/laratables-demo-one-to-many-polymorphic
- https://github.com/freshbitsweb/laratables-demo-one-to-one
Requirements
| PHP | Laravel | Package | |--------|---------|---------| | 8.3+ | 12.x | v5.0.0 | | 8.2+ | 11.x | v4.0.0 | | 8.0+ | 10.x | v3.0.0 | | 8.0+ | 9.x | v2.5.0 | | 7.3+ | 8.x | v2.4.0 | | 7.2.5+ | 7.x | v2.3.0 | | <7.2.5 | 6.x | v2.2.0 | | 7.1 | 5.x | v2.0.* |
Installation
Install the package by running this command in your terminal/cmd:
composer require freshbitsweb/laratables
Optionally, you can import config file by running this command in your terminal/cmd:
php artisan vendor:publish --tag=laratables_config
Customization
Following the steps of How to use section should get you up and running with a simple datatables example in a minute. However, many datatables require customization ability. First use case is about applying additional where conditions to the query or load additional relationships.
To achieve that, you can simply pass a closure/callable as a second parameter to recordsOf() method. It should accept the underlying query as a parameter and return it after applying conditionals:
use App\User;
use Freshbitsweb\Laratables\Laratables;
...
return Laratables::recordsOf(User::class, function($query)
{
return $query->where('active', true);
});
There are many more options to customize query/data/logic. You can add any of the following methods (they start with laratables word) in your model or a custom class to keep your model neat and clean. Specify the name of the custom class as the second argument to the recordsOf() method if you wish to use one:
use App\User;
use Freshbitsweb\Laratables\Laratables;
use App\Laratables\User as UserLaratables;
...
return Laratables::recordsOf(User::class, UserLaratables::class);
Controlling the query
If you wish to apply conditions everytime a model is used to display a Laratable, add laratablesQueryConditions() static method to the model/custom class.
/**
* Fetch only active users in the datatables.
*
* @param \Illuminate\Database\Eloquent\Builder
* @return \Illuminate\Database\Eloquent\Builder
*/
public static function laratablesQueryConditions($query)
{
return $query->where('active', true);
}
This method accepts and returns a $query object.
Controlling the relationship query
You can also control the relationship query by defining a closure which can be used while eager loading the relationship records. The static method name format is laratables[RelationName]RelationQuery.
/**
* Eager load media items of the role for displaying in the datatables.
*
* @return callable
*/
public static function laratablesRoleRelationQuery()
{
return function ($query) {
$query->with('media');
};
}
Joining related tables to the query
The laratablesQueryConditions() method can also be used to add joins on the base table. This is particularly useful if you need to define custom searching and sorting based on related models, for example:
/**
* Join roles to base users table.
* Assumes roles -> users is a one-to-many relationship
*
* @param \Illuminate\Database\Eloquent\Builder
* @return \Illuminate\Database\Eloquent\Builder
*/
public static function laratablesQueryConditions($query)
{
return $query->join('roles', 'roles.id', 'users.role_id');
}
Note - If searching/filtering by columns from the joined table, you will need to also ensure they are included in the selected columns. A couple of options for how to do this include:
- Chaining a
->select()method above - e.g.$query->join(...)->select(['roles.name as role_name']), or - Using the
laratablesAdditionalColumns()method as described in Selecting additional columns below.
Custom columns
Generally, we need one or more columns that are not present in the database table. The most common example is 'Action' column to provide options to edit or delete the record. You can add a static method laratablesCustom[ColumnName]() to your model/custom class to specify the custom column value. As per our example, it could be:
/**
* Returns the action column html for datatables.
*
* @param \App\User
* @return string
*/
public static function laratablesCustomAction($user)
{
return view('admin.users.includes.index_action', compact('user'))->render();
}
As you may have observed, you receive an eloquent object of the record as a parameter to use the record details in your method.
Relationship columns
We also need to display data from related models, right? And it's super easy here. No need to do anything on server side for simple relationships. Just specify the name of the relation and the name of the column on the client side inside columns array.
columns: [
...
{ name: 'role.name', orderable: false },
...
],
Ordering records by a relationship column is not supported in Laravel as main table records are fetched first and another query is fired to fetch related table records. Therefore, you should always keep your relationship table columns to be orderable: false.
Note - The package does not support nested relationships yet. You can utilize the custom column feature to get the nested relationship data but make sure that you eager load the relationship records.
Customizing column values
Sometimes, you m
