# 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())
];
}
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'])
])
];
}
# 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()
])
];
}
# 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)
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)
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>
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')
# 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
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
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.