Data table


Comando

Ejecute el siguiente comando artisan para crear un nuevo componente Livewire con lo necesario para un data table:

    php artisan make:data-table NombreComponente --model=Modelo

Similar al comando para crear componentes de livewire solo que requiere especificar el nombre del modelo.

{info.fa-lightbulb-o} Ejemplo

php artisan make:data-table ListadoUsuarios --model=User

Se han creado dos nuevos archivos en el proyecto:

app/Http/Livewire/ListadoUsuarios.php

resources/views/livewire/listado-usuarios.blade.php

Si desea crear componentes dentro de subcarpetas, puede utilizar las siguiente sintaxis:

    php artisan make:data-table Usuarios/ListadoUsuarios

Para tener acceso a la vista crea una neva ruta en el archivo web

    use App\Http\Livewire\ListadoUsuarios;

    Route::get('usuarios', ListadoUsuarios::class)->name('usuarios');

Definir columnas

Las colummnas que se mostraran en el listado es necesario que se definan dentro del componente de Livewire en el método columns.

app/Http/Livewire/ListadoUsuarios.php

    public function columns()
    {
        return [
            // Columnas
        ];
    }

Tipos de columnas

Columna Vacía

Para generar el tipo de columna más básico, indique el nombre al método name.

    public function columns()
    {
        return [
            Column::name('Columna vacia')
        ];
    }

Columna con solo atributo

Para mostrar un atributo de cada modelo, indique el nombre del atributo al método content.

    public function columns()
    {
        return [
            Column::name('Nombre')->content('name')
        ];
    }

Columna personalizada

Para especificar una columna utilice una Función anonima al o una Funcion flecha en el método content que reciba como parámetro un modelo.

    public function columns()
    {
        return [
            Column::name('Nombre')->content( function ($user) {
                return $user->name
            })
        ];

    }

{info.fa-lightbulb-o} Por ejemplo para que el nombre de un usuario se muestre en mayúsculas

    public function columns()
    {
        return [
            Column::name('Nombre')->content(fn ($user) 
                    => strtoupper($user->name))
        ];
    }

Columna con solo texto

Especifique una función que regrese dicho contenido.

    public function columns()
    {
        return [
            Column::name('Relleno')->content(fn () => "Texto en cada fila")
        ];
    }

Columna con vista

Para que una columna muestre una vista o componente de blade para cada modelo indique el nombre de la vista al método content.

    public function columns()
    {
        return [
            Column::name('Nombre')->content(fn () => view('componente-blade'))
        ];
    }

{info.fa-lightbulb-o} Por ejemplo una vista del archivo listado.blade.php que se encuentra en la carpeta roles y le pasa como atributos permisos que los extrae del modelo.

    public function columns()
    {
        return [
            Column::name('Permisos')->content(fn ($rol) =>
                view('roles.listado', [
                    'permisos' => $rol->permisos,
                ])
            )
        ];
    }

Ocultar columnas

Si requiere mostrar / ocultar una cierta columna solo si se cumple una condición, indique en el método show la condición.

{info.fa-lightbulb-o} Por ejemplo mostrar la opcion de Eliminar solo si el usuario cuenta con el permiso.

    public function columns()
    {
        return [
            Column::name('Eliminar')
                ->show($this->user->hasPermissionTo('delete article'))
                ->content(fn ($articulo) =>
                    view('articles.delete-button', [
                        'article' => $articulo,
                    ])
                )
        ];
    }

Definir filtros

Para incluir los filtros indique el método filter en la vista del componente de Livewire

<div>
  {{ $this->filter() }}
</div>

En el de componente de Livewire se incluye el metodo filters

    public function filters(): array
    {
        return [
            // Filtros
        ];
    }

Nombre del filtro

Para indicar el nombre se usa el método name.

    public function filters(): array
    {
        return [
            Filter::name('Mi filtro')
        ];
    }

{info} Este debe ser el primer método que se llame, el orden de los demás no importa.

Listado de opciones

Las opciones de un select se componen por dos partes:

  • value que el identificador de la opción.
  • contenido que es lo que se muestra al usuario.

Para especificar las opciones utilice el método options.

Este puede recibir un arreglo

Por ejemplo:

    public function filters(): array
    {
        return [
            SelectFilter::name('Estado civil')->options([
                'c' => 'Casado', 
                's' => 'Soltero'
            ])
        ];
    }

o de ser necesario una colección podemos usar el método pluck disponible en todos los modelos para generar esta lista de opciones en el ejemplo siguiente, se extraen todos los permisos del modelo Permission y coloca el id de cada permiso en las keys y el name en los values.

public function filters(): array
    {
        return [
            SelectFilter::name('Permiso')
                ->options(Permission::pluck('name', 'id'))
        ];
    }

{info} La opción por defecto sera Todos.

Personalizar opción por defecto

Para personalizar un valor por defecto utilice el metodo default.

El primer parámetro indica el contenido y el segundo indica el value de la opción.

SelectFilter::name('Color')->default('Cualquiera')
    ->options(['Amarillo', 'Verde', 'Rosa'])
])
SelectFilter::name('Estado')->default(key: "TD")
    ->options(['SE' => 'Sin empezar', 'P' => 'Pendiente', 'T' => 'Terminado'])
])

Aplicar los filtros

Es necesario definir una scope que se aplicará para filtrar los modelos utilice el método scope

Por ejemplo supongamos que tenemos el modelo Alumno que se relaciona con Programa en una relación de muchos a 1 y queremos filtrar los alumnos por programa. El filtro quedaría:

SelectFilter::name('Programa')
    ->options(Programa::pluck('nombre', 'id'))
    ->scope('dondeProgramaEs')

Y para que funcione en el modelo Alumno debe existir la siguiente scope:

use Illuminate\Database\Eloquent\Builder;

class Alumno extends Model
{
    public function scopeDondeProgramaEs(Builder $query, $programa_id)
    {
        $query->where('programa_id', $programa_id);
    }
}

Definir scope de busqueda

Para incluir los filtros indique el método searchBar en la vista del componente de Livewire

<div>
    {{ $this->searchBar() }}
</div>

Para hacer uso del trait Searchable especifica en el modelo el uso del trait.

El trait requiere una variable llamada search de tipo array en el modelo, cada elemento del arreglo indicará por cuál columna se debe buscar.

use DevCucei\RocketmanComponents\Traits\Models\Searchable;
use Illuminate\Database\Eloquent\Model;

class Alumno extends Model
{
    use HasFactory;
    use Searchable;

    // stuff

    public $search = [
        // Columnas y relaciones buscables
    ];
}

Por ejemplo, si nuestro modelo se llama alumno y definimos la siguiente variable, entonces el scope buscaría en la tabla alumnos las columnas: nombres, _apellidopaterno, _apellidomaterno y matricula.

public $search = [
    'nombres',
    'apellido_paterno',
    'apellido_materno',
    'matricula'
];

Para buscar en las columnas de las tablas de las relaciones del modelo especifica el nombre de la relación en conjunto con las columnas que queremos buscar dentro de su tabla.

Por ejemplo para buscar por el correo y alumno tiene relación con user:

public $search = [
    'nombres',
    'apellido_paterno',
    'apellido_materno',
    'matricula'
    'user' => [
        'email'
    ]
];

{info}Este trait permite hacer full-text search, que viene a ser una búsqueda que permite dividir una oración en palabras y generar una búsqueda por cada una. Por defecto está deshabilitada, pero puedes sobreescribir este comportamiento declarando un atributo llamado fullTextSearch.

use DevCucei\RocketmanComponents\Traits\Models\Searchable;
use Illuminate\Database\Eloquent\Model;

class Materia extends Model
{
    use Searchable;

    protected $fullTextSearch = true;

}

Por defecto, el trait busca una scope llamada search en el modelo, pero si implementaste tu propia scope con otro nombre, especifique en la variable searchScopeName

public string $searchScopeName = "buscar";

Placeholder de la barra de busqueda

public string $searchBarPlaceholder = "Escribe aquí...";

Mostrar tabla

En la vista de componente de Livewire se incluye el metodo table

<div>
    {{ $this->table() }}
</div>

Estilos

Para darle estilos, indique en un array dentro del método table

<div>
    {{ $this->table([
        // Styles
    ]) }}
</div>

Estilos a tags

Incluya el estilo del tag como llave y su valor será un array de estilos que se aplicarán.

    {{$this->table([
        'table' => [
            'table table-hover ',
        ]
    ])}}

Tags disponibles:

  • table : Tabla.
  • thead : Cabecera de la tabla.
  • tbody : Contenido de la tabla.
  • tr : Fila.
  • th : Cabecera de columna.
  • td : Celda de una fila.

Ejemplos

Aplica el estilo text-center al header de la columna Roles.

    {{$this->table([
        'th.Roles' => [
            'text-center'
        ],  
    ])}}

Aplica estilos a las celdas de la columna Acciones utiliza el prefijo td.

    {{$this->table([
        'td.Acciones' => [
            'text-center',
            'p-5' => $padding
        ],
    ])}}

{info} En el ejemplo anterior se indica que se aplica el estilo p-5 si la variable $padding se evalua en true.

Aplica estilos dependiedo si se cumple alguna condición con el modelo, los estilos se asociarán a una Closure la cual debe recibir el modelo y devolver un valor booleano.

    {{$this->table([
        'tr' => [
            'text-danger' => fn($m) => $m->id === 1,
        ],
    ])}}

El ejemplo anterior aplica el estilo text-danger a aquellas filas que tengan id igual a 1.