PHPackages                             raprmdn/laravel-inertia-datatables - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. raprmdn/laravel-inertia-datatables

ActiveLibrary[Database &amp; ORM](/categories/database)

raprmdn/laravel-inertia-datatables
==================================

Laravel server-side data table query builder with optional Inertia React components.

v0.1.0(yesterday)11↑2900%MITPHPPHP ^8.2

Since Jun 26Pushed yesterdayCompare

[ Source](https://github.com/raprmdn/laravel-inertia-datatables)[ Packagist](https://packagist.org/packages/raprmdn/laravel-inertia-datatables)[ RSS](/packages/raprmdn-laravel-inertia-datatables/feed)WikiDiscussions master Synced today

READMEChangelog (1)Dependencies (6)Versions (2)Used By (0)

Laravel Inertia Datatables
==========================

[](#laravel-inertia-datatables)

[![Latest Version on Packagist](https://camo.githubusercontent.com/8e17ad6bb98c9e97bf6a15e842e1506928327d8c6342af5c5de31305e3138404/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f726170726d646e2f6c61726176656c2d696e65727469612d646174617461626c65732e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/raprmdn/laravel-inertia-datatables)

> This package is currently in beta. It is usable, but the public API may still change before `v1.0.0`.

`raprmdn/laravel-inertia-datatables` is a Laravel server-side datatable query builder. The current core package is backend-only and can be used with Inertia, API resources, Blade, or any Laravel response.

Installation
------------

[](#installation)

```
composer require raprmdn/laravel-inertia-datatables
```

Publish Config
--------------

[](#publish-config)

```
php artisan vendor:publish --tag=inertia-datatables-config
```

Published file:

```
config/inertia-datatables.php
```

Configuration
-------------

[](#configuration)

```
return [
    'query_params' => [
        'search'    => 'search',
        'filters'   => 'filters',
        'column'    => 'col',
        'direction' => 'sort',
        'limit'     => 'limit',
    ],

    'date_format' => 'd-m-Y',

    'pagination' => [
        'default_per_page' => 10,
        'max_per_page'     => 100,
        'on_each_side'     => 1,
    ],

    'json_columns' => [],
];
```

- `query_params`: request query keys used by search, filters, sorting, and pagination.
- `date_format`: expected incoming date range format.
- `pagination`: default page size, max page size, and paginator link window.
- `json_columns`: columns that should use JSON contains filtering.

Basic Usage
-----------

[](#basic-usage)

```
use App\Models\User;
use Raprmdn\DataTables\Facades\DataTable;

$users = DataTable::query(User::query())
    ->searchable(['name', 'email'])
    ->orderBy('created_at', 'desc')
    ->make();
```

Query Parameters
----------------

[](#query-parameters)

### Search

[](#search)

```
?search=raprmdn
```

```
->searchable(['name', 'email', 'contact.name'])
```

### Filters

[](#filters)

```
?filters[]=status:new&filters[]=priority:High
```

Filters use a mapping where:

- **Key** is the filter name received from the request.
- **Value** is the database column or relationship column.

```
$filterColumns = [
    'status'   => 'status',
    'priority' => 'priority.name',
];

[$columnFilters, $dateRanges] = DataTable::parseFilters(
    $request->query('filters', []),
    $filterColumns
);

DataTable::query($query)
    ->applyFilters($columnFilters)
    ->allowedFilters(array_values($filterColumns))
    ->make();
```

Special filter values: `NULL`, `NOT NULL`.

### Date Range Filters

[](#date-range-filters)

```
?filters[]=created_at_from:01-01-2026&filters[]=created_at_to:31-12-2026
```

Date range filter keys should end with `_from` and `_to`.

```
$filterColumns = [
    'status'          => 'status',
    'created_at_from' => 'created_at_from',
    'created_at_to'   => 'created_at_to',
];

[$columnFilters, $dateRanges] = DataTable::parseFilters(
    $request->query('filters', []),
    $filterColumns
);

DataTable::query($query)
    ->applyFilters($columnFilters)
    ->allowedFilters(array_values($filterColumns))
    ->applyDateRanges($dateRanges)
    ->make();
```

Date input format is controlled by `inertia-datatables.date_format`.

### Sorting

[](#sorting)

```
?col=created_at&sort=desc
```

Sorting uses a mapping where:

- **Key** is the column name received from the request.
- **Value** is the database column or relationship column.

```
$sortColumns = [
    'name'       => 'name',
    'email'      => 'email',
    'created_at' => 'created_at',
];

[$sort, $allowedSorts] = DataTable::parseSort(
    $request->query('col'),
    $sortColumns
);

DataTable::query($query)
    ->applySort($sort)
    ->allowedSorts($allowedSorts)
    ->orderBy('created_at', 'desc')
    ->make();
```

Only `asc` and `desc` directions are valid. Invalid sort columns fallback to the default order.

If the requested column is empty or not found in the mapping, `$sort` will be `null` and the DataTable will use the default `orderBy()` column.

### Pagination

[](#pagination)

```
?limit=25
```

```
DataTable::query($query)
    ->perPage(25)
    ->make();
```

Use collection output when pagination is not needed:

```
DataTable::query($query)
    ->type('collection')
    ->make();
```

Relations
---------

[](#relations)

Searching, filtering, and sorting support relationship columns using **dot notation**.

```
'contact.name'
'priority.sla_minutes'
'reason.parent.name'
```

The first part is the **relationship method** defined on your Eloquent model, and the last part is the **column** on the related table.

For example:

```
'contact.name'
```

- `contact` → `contact()` relationship defined in the `Ticket` model.
- `name` → `name` column in the `contacts` table.

Nested relationships are also supported:

```
'reason.parent.name'
```

- `reason` → relationship on `Ticket`
- `parent` → relationship on `Reason`
- `name` → column in the parent relation table.

Use Laravel relationship names for eager loading:

```
->with(['contact.channel', 'priority'])
->withCount(['tickets'])
```

> **Note:** Relation sorting currently supports `BelongsTo` and `HasOne` relationships. Sorting on ambiguous relationships such as `HasMany` or `BelongsToMany` may throw an exception.

Available Methods
-----------------

[](#available-methods)

- `query($query)`: set the Eloquent or query builder instance.
- `with([...])`: eager load relationships.
- `withCount([...])`: eager load relationship counts.
- `searchable([...])`: set searchable columns and relation columns.
- `applyFilters([...])`: apply parsed filters.
- `allowedFilters([...])`: whitelist filter columns.
- `applyDateRanges([...])`: apply parsed date ranges.
- `applySort($column)`: set requested sort column. Accepts `null` to use default ordering.
- `allowedSorts([...])`: whitelist sort columns.
- `DataTable::parseFilters($filters, $filterColumns)`: parse request filters into column filters and date ranges.
- `DataTable::parseSort($column, $sortColumns)`: parse requested sort column and allowed sorts from one mapping.
- `orderBy($column, $direction)`: set fallback order.
- `perPage($limit)`: set default pagination limit.
- `type('pagination')`: return paginated results.
- `type('collection')`: return collection results.
- `make()`: execute the query.

Helper Methods
--------------

[](#helper-methods)

### `DataTable::parseFilters()`

[](#datatableparsefilters)

`DataTable::parseFilters()` converts request filters into:

1. `$columnFilters` — normal column or relationship filters for `applyFilters()`.
2. `$dateRanges` — date range filters for `applyDateRanges()`.

It accepts 2 parameters:

```
DataTable::parseFilters(
    $request->query('filters', []),
    $filterColumns
);
```

Example filter mapping:

```
$filterColumns = [
    'status'          => 'status',
    'channel'         => 'contact.channel.name',
    'created_at_from' => 'created_at_from',
    'created_at_to'   => 'created_at_to',
];
```

Example request:

```
?filters[]=status:closed
&filters[]=channel:Instagram
&filters[]=created_at_from:01-05-2026
&filters[]=created_at_to:30-06-2026

```

Usage:

```
[$columnFilters, $dateRanges] = DataTable::parseFilters(
    $request->query('filters', []),
    $filterColumns
);
```

Result:

```
$columnFilters = [
    'status:closed',
    'contact.channel.name:Instagram',
];

$dateRanges = [
    'created_at' => [
        'from' => '01-05-2026',
        'to'   => '30-06-2026',
    ],
];
```

Then pass the result to the DataTable:

```
DataTable::query($query)
    ->applyFilters($columnFilters)
    ->allowedFilters(array_values($filterColumns))
    ->applyDateRanges($dateRanges)
    ->make();
```

### `DataTable::parseSort()`

[](#datatableparsesort)

`DataTable::parseSort()` converts a request sort key into:

1. `$sort` — selected database or relationship column for `applySort()`.
2. `$allowedSorts` — allowed sortable columns for `allowedSorts()`.

It accepts 2 parameters:

```
DataTable::parseSort(
    $request->query('col'),
    $sortColumns
);
```

Example sort mapping:

```
$sortColumns = [
    'ticket'   => 'number',
    'channel'  => 'contact.channel.name',
    'priority' => 'priority.sla_minutes',
];
```

Example request:

```
?col=channel&sort=asc

```

Usage:

```
[$sort, $allowedSorts] = DataTable::parseSort(
    $request->query('col'),
    $sortColumns
);
```

Result:

```
$sort = 'contact.channel.name';

$allowedSorts = [
    'number',
    'contact.channel.name',
    'priority.sla_minutes',
];
```

Then pass the result to the DataTable:

```
DataTable::query($query)
    ->applySort($sort)
    ->allowedSorts($allowedSorts)
    ->make();
```

Example Inertia Controller
--------------------------

[](#example-inertia-controller)

```
use App\Http\Resources\ContactResource;
use App\Http\Resources\TicketResource;
use App\Models\Contact;
use App\Models\Ticket;
use Illuminate\Http\Request;
use Raprmdn\DataTables\Facades\DataTable;

public function show(Request $request, Contact $contact)
{
    $contact->load(['channel', 'createdBy']);

    $query = Ticket::query()->where('contact_id', $contact->id);

    $filterColumns = [
        'status'          => 'status',
        'priority'        => 'priority.name',
        'channel'         => 'contact.channel.name',
        'reason_type'     => 'reason.parent.name',
        'department'      => 'department.name',
        'assigned'        => 'assignedTo.name',
        'created_by'      => 'creator.name',
        'created_at_from' => 'created_at_from',
        'created_at_to'   => 'created_at_to',
    ];

    [$columnFilters, $dateRanges] = DataTable::parseFilters(
        $request->query('filters', []),
        $filterColumns
    );

    $sortColumns = [
        'ticket'     => 'number',
        'status'     => 'status',
        'priority'   => 'priority.sla_minutes',
        'channel'    => 'contact.channel.name',
        'customer'   => 'contact.name',
        'department' => 'department.name',
        'assigned'   => 'assignedTo.name',
        'created_at' => 'created_at',
        'updated_at' => 'updated_at',
        'created_by' => 'creator.name',
    ];

    [$sort, $allowedSorts] = DataTable::parseSort(
        $request->query('col'),
        $sortColumns
    );

    $tickets = DataTable::query($query)
        ->with([
            'priority',
            'assignedTo',
            'contact.channel',
            'department',
            'reason.parent',
            'reason',
            'subReason',
            'creator',
            'updater',
        ])
        ->searchable([
            'number',
            'reason.name',
            'reason.parent.name',
            'subReason.name',
            'contact.name',
            'contact.email',
            'contact.phone',
        ])
        ->applySort($sort)
        ->allowedSorts($allowedSorts)
        ->applyFilters($columnFilters)
        ->allowedFilters(array_values($filterColumns))
        ->applyDateRanges($dateRanges)
        ->make();

    return inertia('contact/show', [
        'contact' => ContactResource::make($contact),
        'tickets' => TicketResource::collection($tickets),
    ]);
}
```

API Example
-----------

[](#api-example)

```
use App\Http\Resources\UserResource;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use Raprmdn\DataTables\Facades\DataTable;

Route::get('/users', function (Request $request) {
    $sortColumns = [
        'name'       => 'name',
        'email'      => 'email',
        'created_at' => 'created_at',
    ];

    [$sort, $allowedSorts] = DataTable::parseSort(
        $request->query('col'),
        $sortColumns
    );

    $users = DataTable::query(User::query())
        ->searchable(['name', 'email'])
        ->applySort($sort)
        ->allowedSorts($allowedSorts)
        ->make();

    return UserResource::collection($users);
});
```

Inertia React Components
------------------------

[](#inertia-react-components)

This package currently focuses on the Laravel backend query builder.

Publishable Inertia React starter components are planned for a future release. Until that release, you can use this package with your own Inertia, React, Vue, Blade, or API frontend.

Known Limitations
-----------------

[](#known-limitations)

- Beta release, API may change.
- Inertia React components are planned but not part of the current beta release.
- String column and relation names inside arrays may not get perfect IDE autocomplete.
- Relation sorting does not support every relation type.
- Advanced filter operators are not implemented yet.

Roadmap
-------

[](#roadmap)

- Tests
- Better documentation
- More filter operators
- Optional Inertia React starter components
- Column definitions API

Contributing
------------

[](#contributing)

Issues and pull requests are welcome while the package is in beta. Keep changes focused and backend-first unless the change is explicitly about planned frontend starter components.

License
-------

[](#license)

This package is open-sourced software licensed under the MIT license.

###  Health Score

38

—

LowBetter than 83% of packages

Maintenance100

Actively maintained with recent releases

Popularity4

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity35

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

1d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/71953516?v=4)[Rafi Putra Ramadhan](/maintainers/raprmdn)[@raprmdn](https://github.com/raprmdn)

---

Top Contributors

[![raprmdn](https://avatars.githubusercontent.com/u/71953516?v=4)](https://github.com/raprmdn "raprmdn (5 commits)")

### Embed Badge

![Health badge](/badges/raprmdn-laravel-inertia-datatables/health.svg)

```
[![Health](https://phpackages.com/badges/raprmdn-laravel-inertia-datatables/health.svg)](https://phpackages.com/packages/raprmdn-laravel-inertia-datatables)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3345.1M337](/packages/psalm-plugin-laravel)[laravel/cashier

Laravel Cashier provides an expressive, fluent interface to Stripe's subscription billing services.

2.5k28.4M137](/packages/laravel-cashier)[api-platform/laravel

API Platform support for Laravel

59156.3k11](/packages/api-platform-laravel)[yajra/laravel-oci8

Oracle DB driver for Laravel via OCI8

8723.1M23](/packages/yajra-laravel-oci8)[pressbooks/pressbooks

Pressbooks is an open source book publishing tool built on a WordPress multisite platform. Pressbooks outputs books in multiple formats, including PDF, EPUB, web, and a variety of XML flavours, using a theming/templating system, driven by CSS.

45344.0k1](/packages/pressbooks-pressbooks)[fleetbase/core-api

Core Framework and Resources for Fleetbase API

1232.2k16](/packages/fleetbase-core-api)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
