# Elementos

Los elementos pueden ser usados y combinados en las secciones custom:

# DataTable

Corresponde al mismo listado de datos utilizado en las secciones estándar.
Se usa para mostrar un listado de filas y columnas.
Se pueden usar los mismos tipos de campo que en las secciones estándar, pasando un array como segundo parámetro:

public function elements(): array
{
    return [
         DataTable::make('Listado de paises', [
            TextField::make('Nombre', 'name'),
            TextField::make('ISO Code', 'iso_code')
        ])->fromQuery(Country::query())
    ];
}

DataTable1

Notar que los datos devueltos pueden ser personalizados mediante el objeto Builder proporcionado en la función fromQuery().

# Filtros

Se pueden usar los mismos tipos de filtros que en las secciones estándar, mediante la función setFilters():

public function elements(): array
{
    return [
         DataTable::make('Listado de paises', [
            TextField::make('Nombre', 'name'),
            TextField::make('ISO Code', 'iso_code')
        ])
            ->fromQuery(Country::query())
            ->setFilters([
                SearchFilter::make(['name'])
            ])
    ];
}

DataTable2

# Acciones de elemento

Se pueden espeficar Acciones de elemento, por ejemplo para eliminar un registro:

public function elements(): array
{
    return [
         DataTable::make('Listado de paises', [
            TextField::make('Nombre', 'name'),
            TextField::make('ISO Code', 'iso_code')
        ])
            ->fromQuery(Country::query())
            ->setItemActions([
                DeleteItemAction::make()
            ])
    ];
}

DataTable3

# Acciones disponibles

Listado de acciones

El listado de accciones predefinidas y cómo crear acciones personalizadas puede encontrarse en la sección Acciones

# DataForm

Corresponde al mismo tipo de formulario utilizado en las secciones estándar.
Se pueden usar los mismos tipos de campo que en las secciones estándar, pasando un array como segundo parámetro:

DataForm::make('Nuevo pais', [
    TextField::make('Nombre', 'name')->required(),
    TextField::make('ISO Code', 'iso_code')->required(),
])->saveWith(Country::class)

DataForm1

Mediante la función saveWith() se especifica el modelo a utilizar para guardar los datos.

# Acción después de guardar

La función saveWith() admite un segundo parámetro donde se le puede especificar un callback a ejecutar justo después del guardado. Puede servir por ejemplo para enviar un email, actualizar el estado de un proceso, etc.
En la función anónima se recibe la Request, un objeto de tipo Model con los datos del registro creado / actualizado y la URL de vuelta a la sección (para aplicar una redirección)

DataForm::make('Nuevo pais', [
    TextField::make('Nombre', 'name')->required(),
    TextField::make('ISO Code', 'iso_code')->required(),
])
    ->saveWith(Country::class, function (Request $request, Model $item) {
        // Aqui realizamos alguna acción
    })

# Acción custom al enviar

En ocasiones el envio del formulario no implica crear / editar un registro asociado a un modelo, si no que se requiere algo más custom, como subir un archivo, enviar un email, modificar más de una tabla, etc.
Para ello existe la función onSubmit() donde proporcionando un callback se ejecutará al ser enviado el formulario, recibiendo el objeto Request con los datos del formulario:

DataForm::make('Nuevo pais', [
    TextField::make('Nombre', 'name')->required(),
    TextField::make('ISO Code', 'iso_code')->required(),
])
    ->onSubmit(function (Request $request) {
        // Aquí realizamos acciones
    })

# Origen de datos

Los campos del formulario pueden estar asociados a un registro de base de datos.
Para ello, se puede pasar como tercer parámetro un objeto de tipo Model:




 

DataForm::make('Modificar pais', [
    TextField::make('Nombre', 'name')->required(),
    TextField::make('ISO Code', 'iso_code')->required(),
], Country::query()->find(1))

# DataFormMultiple

Similar al DataForm, se usa cuando se necesita una interfaz desde la cual poder editar varios registros a la vez.
Los parámetros son idénticos al DataForm, con la diferencia que como tercer parámetro se deberá especificar el origen de datos obligatoriamente, bien como Collection procedente de una query o como array:

DataForm::make('Paises', [
    TextField::make('Nombre', 'name')->required(),
    Checkbox::make('Activo', 'active'),
], Country::query()->get())->saveWith(Country::class)

DataFormMultiple

Limitaciones

Tener en cuenta que la disposición de los campos es en columna y NO ES POSIBLE agrupar o apilar campos con GroupFields o StackFields.

# Card

Es usado cuando se necesita una interfaz y datos personalizados.
El elemento Card tiene como primer parámetro el nombre de la vista (con notación backoffice::).
Como segundo parámetro una función donde se retornarán los valores para la vista. Dicha función recibe el objeto Request.

Card::make('backoffice::products', function (Request $request) {
    $products = Product::query()
        ->orderByDesc('sales')
        ->pluck('sales', 'name');

    return ['products' => $products];
})
<!-- resources/views/vendor/backoffice/products.blade.php -->
<table>
    <tr>
        <th>Nombre</th>
        <th>Ventas</th>
    </tr>
    @foreach ($products as $name => $sales)
    <tr>
        <td>{{ $name }}</td>
        <td class="fit">{{ $sales }}</td>
    </tr>
    @endforeach
</table>

Card1

Se puede especificar un nombre que aparecerá por encima de la caja, mediante la función title():

Card::make('backoffice.products', function (Request $request) {
    $products = Product::query()
        ->orderByDesc('sales')
        ->pluck('sales', 'name');

    return ['products' => $products];
})->title('Productos más vendidos')

Card2

# Personalizar CSS

Para las vistas custom es muy posible que necesites aplicar estilos CSS específicos.
Para ello podemos hacer uso de los Stacks de Laravel Blade (opens new window), mediante el nombre de stack css:


 












 
 
 
 
 
 
 
 
 
 
 
 

<!-- resources/views/vendor/backoffice/products.blade.php -->
<table id="table-products">
    <tr>
        <th>Nombre</th>
        <th>Ventas</th>
    </tr>
    @foreach ($products as $name => $sales)
    <tr>
        <td>{{ $name }}</td>
        <td class="fit">{{ $sales }}</td>
    </tr>
    @endforeach
</table>

@push('css')
    <style>
        #table-products th {
            background-color: #c2d8e4;
        }

        #table-products td {
            background-color: #f7ede8;
            border: 0;
        }
    </style>
@endpush

CSS1

También es posible que en vez de escribir CSS inline hagas referencia a un archivo CSS.
Por ejemplo, si el CSS está en public/backoffice/css/products.css

/* public/backoffice/css/products.css */
#table-products th {
    background-color: #c2d8e4;
}

#table-products td {
    background-color: #f7ede8;
    border: 0;
}
@push('css')
    <link rel="stylesheet" href="{{ asset('backoffice/css/products.css') }}">
@endpush

Scoping

Los stacks se aplican justo después del CSS principal, con lo que es recomendable que el CSS sea específico, por ejemplo, definiendo un id para no interferir con el resto de CSS global.

En el ejemplo anterior a la tabla se le aplica id="table-products" y los estilos van precedidos por #table-products.

Estilos globales

También puede que necesites aplicar estilos globales a todo el backoffice.
Ésto se cubre desde la sección CSS.

# Personalizar Javascript

Para las vistas custom es muy posible que necesites aplicar código Javascript específico.
Para ello podemos hacer uso de los Stacks de Laravel Blade (opens new window), mediante el nombre de stack js:













 
 
 
 
 
 
 
 
 
 





























<div id="users">
    @foreach ($users as $user)
    <div class="user">
        <a href="#">{{ $user->name }} <x-icon name="arrow-right-s-line" /></a>
        <div class="details">
            <p><strong>Ventas: </strong> {{ $user->sales }}</p>
            <p><strong>Último login: </strong> {{ $user->lastLogin }}</p>
        </div>
    </div>
    @endforeach
</div>

@push('js')
    <script>
        $(function() {
            $('.user a').on('click', function() {
                $('.details').hide();
                $(this).next().slideDown();
            });
        });
    </script>
@endpush

@push('css')
    <style>
        #users .user {
            margin: 6px 0;
        }

        #users .user a {
            display: flex;
            justify-content: space-between;
            align-items: center;
            color: #666;
            font-weight: bold;
            background-color: #e2e2e2;
            padding: 8px;
        }

        #users .user a .icon {
            font-size: 1.2rem;
        }

        #users .details {
            display: none;
            background-color: #fbfbfb;
            padding: 10px;
        }
    </style>
@endpush

JS1

Librerías Javascript

Por defecto se incluye la librería jQuery, pero es posible utilizar otras librerías como Vue incluyéndolas, bien mediante los stacks en vistas específicas, como de forma global.