PHPackages                             esolutions/datatable - 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. [Utility &amp; Helpers](/categories/utility)
4. /
5. esolutions/datatable

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

esolutions/datatable
====================

Server-side DataTable, dialogs and Excel exports for Laravel

v1.2.2(2mo ago)00proprietaryPHPPHP ^8.2

Since May 13Pushed 5d agoCompare

[ Source](https://github.com/eriquegasparcarlos/esolutions-datatable)[ Packagist](https://packagist.org/packages/esolutions/datatable)[ RSS](/packages/esolutions-datatable/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (3)Versions (6)Used By (0)

esolutions/datatable
====================

[](#esolutionsdatatable)

Infraestructura para tablas server-side con paginación, filtros, columnas, diálogos de confirmación y exportación Excel.

Instalación
-----------

[](#instalación)

```
composer require esolutions/datatable
```

Namespace
---------

[](#namespace)

```
Esolutions\Datatable\

```

Dependencias
------------

[](#dependencias)

- `esolutions/laravel` — para `ApiResponse` y `AuthHelper`
- `maatwebsite/excel` — para exportación Excel

---

Uso completo — ejemplo de un módulo
-----------------------------------

[](#uso-completo--ejemplo-de-un-módulo)

Cada módulo define un DataTable como trait y lo usa en su controlador:

```
// Modules/Plan/DataTables/PlanDataTable.php
use Esolutions\Datatable\Table\{Button, ButtonBuilder, Column, ColumnBuilder, Filter, FilterBuilder};
use Esolutions\Datatable\Traits\PaginationSystemTrait;

trait PlanDataTable
{
    use PaginationSystemTrait;

    protected function getTableConfig(): array
    {
        return [
            'page_title'  => __('plans title page'),
            'table_title' => __('plans title table'),
            'table_name'  => 'plans',
        ];
    }

    protected function getHeaderButtons(): array
    {
        return (new ButtonBuilder())
            ->addButton(Button::newButton())
            ->addButton(Button::refreshButton())
            ->addButtonGroup([Button::exportButton()])
            ->getButtons();
    }

    protected function getColumns(): array
    {
        return (new ColumnBuilder())
            ->addColumn(Column::make('name')->label('Nombre'))
            ->addColumn(Column::make('price')->label('Precio')->alignRight()->width('100px'))
            ->addColumn(Column::isActive())
            ->addColumn(Column::actions())
            ->getColumns();
    }

    protected function getFilters(): array
    {
        return (new FilterBuilder())
            ->addFilter(Filter::makeInput('search')->label('Buscar')->cssClass('col-12'))
            ->getFilters();
    }
}
```

```
// Modules/Plan/Http/Controllers/PlanController.php
use Esolutions\Datatable\Dialog\DialogAction;
use Esolutions\Datatable\Dialog\Requests\ActionRequest;
use Esolutions\Laravel\Auth\AuthHelper;
use Esolutions\Laravel\Http\ApiResponse;

class PlanController extends Controller
{
    use PlanDataTable;

    // GET /plans/record/{id}
    public function record($id) { ... }

    // POST /plans/store
    public function store(PlanRequest $request) { ... }

    // GET /plans/record-active/{id}
    public function recordActive($id)
    {
        $record = Plan::findOrFail($id);
        return DialogAction::getActiveRecordActionData($record, 'name', 'plan');
    }

    // POST /plans/store-active
    public function storeActive(ActionRequest $request)
    {
        $password = $request->input('password');
        if ($password && !AuthHelper::checkPassword($password)) {
            return ApiResponse::error('La contraseña es incorrecta', 403);
        }
        $record = Plan::findOrFail($request->input('id'));
        $record->update(['is_active' => !$record->is_active]);
        return ApiResponse::success($record->is_active ? 'Activado' : 'Desactivado');
    }

    // GET /plans/record-delete/{id}
    public function recordDelete($id)
    {
        $record = Plan::findOrFail($id);
        return DialogAction::getDeleteRecordActionData($record, 'name', 'plan');
    }

    // POST /plans/delete
    public function storeDelete(ActionRequest $request)
    {
        $password = $request->input('password');
        if ($password && !AuthHelper::checkPassword($password)) {
            return ApiResponse::error('La contraseña es incorrecta', 403);
        }
        Plan::findOrFail($request->input('id'))->delete();
        return ApiResponse::success('Plan eliminado');
    }
}
```

---

Dialog — `DialogAction`
-----------------------

[](#dialog--dialogaction)

Genera la configuración del diálogo de confirmación que el frontend renderiza.

### `getDeleteRecordActionData`

[](#getdeleterecordactiondata)

```
DialogAction::getDeleteRecordActionData(
    record: $record,
    nameField: 'name',       // campo que muestra el nombre en el diálogo
    type: 'plan',            // texto del tipo de registro
    verifyPassword: false    // true = el frontend muestra campo de contraseña
);
```

Retorna:

```
{
    "title": "Eliminar plan",
    "description": "¿Está seguro que desea eliminar el plan Básico?",
    "button_label_submit": "Eliminar",
    "button_color": "red",
    "icon": "triangle-exclamation",
    "icon_color": "red",
    "verify_password": false
}
```

### `getActiveRecordActionData`

[](#getactiverecordactiondata)

```
DialogAction::getActiveRecordActionData($record, 'name', 'plan');
```

Detecta el estado actual (`is_active`) y retorna el texto correspondiente (Activar / Desactivar).

### `getActionData`

[](#getactiondata)

Para acciones personalizadas:

```
DialogAction::getActionData(
    title: 'Sincronizar datos',
    description: '¿Desea sincronizar con SUNAT?',
    options: ['button_color' => 'primary', 'verify_password' => true]
);
```

---

Dialog — `ActionRequest`
------------------------

[](#dialog--actionrequest)

FormRequest estándar para los endpoints `storeDelete` y `storeActive`.

**Reglas de validación:**

CampoRegla`id``required``password``nullable`, `required_if:verify_password,true`---

Table — Columnas
----------------

[](#table--columnas)

### `Column`

[](#column)

```
use Esolutions\Datatable\Table\Column;

Column::make('name')->label('Nombre')
Column::make('price')->label('Precio')->alignRight()->width('100px')
Column::make('date')->label('Fecha')->alignCenter()
Column::isActive()    // columna estándar de estado activo/inactivo
Column::actions()     // columna estándar de botones de acción
```

### `ColumnBuilder`

[](#columnbuilder)

```
use Esolutions\Datatable\Table\ColumnBuilder;

$columns = (new ColumnBuilder())
    ->addColumn(Column::make('name')->label('Nombre'))
    ->addColumn(Column::isActive())
    ->addColumn(Column::actions())
    ->getColumns();
```

---

Table — Filtros
---------------

[](#table--filtros)

### `Filter`

[](#filter)

```
use Esolutions\Datatable\Table\Filter;

Filter::makeInput('search')->label('Buscar')->cssClass('col-12')
Filter::makeSelect('status')->label('Estado')->options([
    ['id' => 'all', 'name' => 'Todos'],
    ['id' => 1,     'name' => 'Activo'],
    ['id' => 0,     'name' => 'Inactivo'],
])
```

### `FilterBuilder`

[](#filterbuilder)

```
use Esolutions\Datatable\Table\FilterBuilder;

$filters = (new FilterBuilder())
    ->addFilter(Filter::makeInput('search')->label('Buscar')->cssClass('col-24 col-sm-12'))
    ->getFilters();
```

---

Table — Botones de cabecera
---------------------------

[](#table--botones-de-cabecera)

```
use Esolutions\Datatable\Table\{Button, ButtonBuilder};

$buttons = (new ButtonBuilder())
    ->addButton(Button::newButton())
    ->addButton(Button::refreshButton())
    ->addButtonGroup([Button::exportButton()])
    ->getButtons();
```

BotónDescripción`Button::newButton()`Abre el formulario de creación`Button::refreshButton()`Recarga la tabla`Button::exportButton()`Exporta a Excel---

Traits de paginación
--------------------

[](#traits-de-paginación)

### `PaginationSystemTrait`

[](#paginationsystemtrait)

Para tablas en el contexto del sistema central (base de datos `central`).

### `PaginationTenantTrait`

[](#paginationtenanttrait)

Para tablas dentro del contexto de un tenant.

```
use Esolutions\Datatable\Traits\PaginationSystemTrait;
// o
use Esolutions\Datatable\Traits\PaginationTenantTrait;
```

Ambos proveen: `updatePagination()`, `$perPage`, `$sortBy`, `$direction`, `$metaAdditional`.

---

Exports — `GenericReportExport`
-------------------------------

[](#exports--genericreportexport)

Exportador Excel reutilizable con título, encabezados estilizados y datos.

```
use Esolutions\Datatable\Exports\GenericReportExport;
use Maatwebsite\Excel\Facades\Excel;

public function exportRecords(Request $request)
{
    $records = Plan::all()->map(fn($r) => [$r->name, $r->price])->toArray();

    return Excel::download(
        new GenericReportExport(
            data: $records,
            headings: ['Nombre', 'Precio'],
            title: 'Reporte de Planes'
        ),
        'reporte_planes.xlsx'
    );
}
```

**Formato del Excel generado:**

- **Fila 1:** Título centrado, negrita, tamaño 18, combinado en todas las columnas
- **Fila 2:** Encabezados con fondo azul `#1976d2`, texto blanco, negrita
- **Filas de datos:** Bordes grises, texto envuelto, columnas auto-dimensionadas

###  Health Score

39

—

LowBetter than 84% of packages

Maintenance94

Actively maintained with recent releases

Popularity0

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity50

Maturing project, gaining track record

 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

Every ~4 days

Total

4

Last Release

61d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/57302658?v=4)[eriquegasparcarlos](/maintainers/eriquegasparcarlos)[@eriquegasparcarlos](https://github.com/eriquegasparcarlos)

---

Top Contributors

[![eriquegasparcarlos](https://avatars.githubusercontent.com/u/57302658?v=4)](https://github.com/eriquegasparcarlos "eriquegasparcarlos (14 commits)")

### Embed Badge

![Health badge](/badges/esolutions-datatable/health.svg)

```
[![Health](https://phpackages.com/badges/esolutions-datatable/health.svg)](https://phpackages.com/packages/esolutions-datatable)
```

###  Alternatives

[unopim/unopim

UnoPim Laravel PIM

10.5k2.4k](/packages/unopim-unopim)[typicms/base

A modular multilingual CMS built with Laravel, enabling developers to manage structured content like pages, news, events, and more.

1.6k20.4k](/packages/typicms-base)[dcat-plus/laravel-admin

dcat-plus admin

1474.1k10](/packages/dcat-plus-laravel-admin)[tomshaw/electricgrid

A feature-rich Livewire package designed for projects that require dynamic, interactive data tables.

119.4k](/packages/tomshaw-electricgrid)[ronasit/laravel-helpers

Provided helpers function and some helper class.

2085.6k31](/packages/ronasit-laravel-helpers)[team-nifty-gmbh/tall-datatables

Server-side rendered datatables for Laravel and Livewire

1320.9k4](/packages/team-nifty-gmbh-tall-datatables)

PHPackages © 2026

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