Validation
Introducción
Se pueden añadir reglas de validación a cualquier campo.
En Laravel, las reglas de validación suelen definirse en arrays como ['required', 'max:255'] o en una cadena combinada como required|max:255. Esto está bien si trabajas exclusivamente en el backend con solicitudes de formulario simples. Pero Filament también puede ofrecer validación en el frontend, para que tus usuarios corrijan errores antes de que se realicen solicitudes al backend.
Filament incluye muchos métodos de validación dedicados, pero también puedes usar otras reglas de validación de Laravel, incluidas reglas personalizadas.
Algunas reglas de validación predeterminadas de Laravel dependen de nombres de atributos correctos y no funcionarán cuando se pasen mediante rule()/rules(). Usa los métodos de validación dedicados siempre que puedas.
Available rules
Active URL
El campo debe tener un registro A o AAAA válido según la función de PHP dns_get_record(). Consulta la documentación de Laravel.
Field::make('name')->activeUrl()
After (date)
El valor del campo debe ser una fecha posterior a otra dada. Consulta la documentación de Laravel.
Field::make('start_date')->after('tomorrow')
Alternativamente, puedes pasar el nombre de otro campo para compararlo:
Field::make('start_date')
Field::make('end_date')->after('start_date')
After or equal to (date)
El valor del campo debe ser una fecha posterior o igual a la dada. Consulta la documentación de Laravel.
Field::make('start_date')->afterOrEqual('tomorrow')
Alternativamente, puedes pasar el nombre de otro campo para compararlo:
Field::make('start_date')
Field::make('end_date')->afterOrEqual('start_date')
Alpha
El campo debe contener únicamente caracteres alfabéticos. Consulta la documentación de Laravel.
Field::make('name')->alpha()
Alpha Dash
El campo puede contener caracteres alfanuméricos, así como guiones y guiones bajos. Consulta la documentación de Laravel.
Field::make('name')->alphaDash()
Alpha Numeric
El campo debe contener únicamente caracteres alfanuméricos. Consulta la documentación de Laravel.
Field::make('name')->alphaNum()
ASCII
El campo debe contener únicamente caracteres ASCII de 7 bits. Consulta la documentación de Laravel.
Field::make('name')->ascii()
Before (date)
El valor del campo debe ser una fecha anterior a una dada. Consulta la documentación de Laravel.
Field::make('start_date')->before('first day of next month')
Alternativamente, puedes pasar el nombre de otro campo para compararlo:
Field::make('start_date')->before('end_date')
Field::make('end_date')
Before or equal to (date)
El valor del campo debe ser una fecha anterior o igual a la dada. Consulta la documentación de Laravel.
Field::make('start_date')->beforeOrEqual('end of this month')
Alternativamente, puedes pasar el nombre de otro campo para compararlo:
Field::make('start_date')->beforeOrEqual('end_date')
Field::make('end_date')
Confirmed
El campo debe tener un campo coincidente {field}_confirmation. Consulta la documentación de Laravel.
Field::make('password')->confirmed()
Field::make('password_confirmation')
Different
El valor del campo debe ser diferente a otro. Consulta la documentación de Laravel.
Field::make('backup_email')->different('email')
Doesn't Start With
El campo no debe comenzar con ninguno de los valores dados. Consulta la documentación de Laravel.
Field::make('name')->doesntStartWith(['admin'])
Doesn't End With
El campo no debe terminar con ninguno de los valores dados. Consulta la documentación de Laravel.
Field::make('name')->doesntEndWith(['admin'])
Ends With
El campo debe terminar con uno de los valores dados. Consulta la documentación de Laravel.
Field::make('name')->endsWith(['bot'])
Enum
El campo debe contener un valor enum válido. Consulta la documentación de Laravel.
Field::make('status')->enum(MyStatus::class)
Exists
El valor del campo debe existir en la base de datos. Consulta la documentación de Laravel.
Field::make('invitation')->exists()
De forma predeterminada, se buscará en el modelo del formulario, si está registrado. Puedes especificar una tabla o modelo personalizado donde buscar:
use App\Models\Invitation;
Field::make('invitation')->exists(table: Invitation::class)
Por defecto, se usará el nombre del campo como columna a buscar. Puedes especificar una columna personalizada:
Field::make('invitation')->exists(column: 'id')
Puedes personalizar aún más la regla pasando un closure al parámetro modifyRuleUsing:
use Illuminate\Validation\Rules\Exists;
Field::make('invitation')
->exists(modifyRuleUsing: function (Exists $rule) {
return $rule->where('is_active', 1);
})
La regla exists de Laravel no usa el modelo Eloquent para consultar la base de datos por defecto, por lo que no aplicará ningún scope global definido en el modelo, incluidos los de soft-deletes. Por ello, incluso si existe un registro con soft-delete con el mismo valor, la validación pasará.
Dado que no se aplican scopes globales, la característica de multi-tenant de Filament tampoco delimita la consulta al tenant actual por defecto.
Para ello, debes usar el método scopedExists(), que reemplaza la implementación exists de Laravel por una que use el modelo para consultar la base de datos, aplicando cualquier scope global definido en el modelo, incluidos soft-deletes y multi-tenant:
use Filament\Forms\Components\TextInput;
TextInput::make('email')
->scopedExists()
Si deseas modificar la consulta Eloquent usada para comprobar la presencia, incluido eliminar un scope global, puedes pasar una función al parámetro modifyQueryUsing:
use Filament\Forms\Components\TextInput;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
TextInput::make('email')
->scopedExists(modifyQueryUsing: function (Builder $query) {
return $query->withoutGlobalScope(SoftDeletingScope::class);
})
Filled
El campo no debe estar vacío cuando está presente. Consulta la documentación de Laravel.
Field::make('name')->filled()
Greater than
El valor del campo debe ser mayor que otro. Consulta la documentación de Laravel.
Field::make('newNumber')->gt('oldNumber')
Greater than or equal to
El valor del campo debe ser mayor o igual que otro. Consulta la documentación de Laravel.
Field::make('newNumber')->gte('oldNumber')
Hex color
El valor del campo debe ser un color hexadecimal válido. Consulta la documentación de Laravel.
Field::make('color')->hexColor()
In
El campo debe estar incluido en la lista de valores proporcionada. Consulta la documentación de Laravel.
Field::make('status')->in(['pending', 'completed'])
Los campos toggle buttons, checkbox list, radio y select aplican automáticamente la regla in() según sus opciones disponibles, por lo que no necesitas añadirla manualmente.
Ip Address
El campo debe ser una dirección IP. Consulta la documentación de Laravel.
Field::make('ip_address')->ip()
Field::make('ip_address')->ipv4()
Field::make('ip_address')->ipv6()
JSON
El campo debe ser una cadena JSON válida. Consulta la documentación de Laravel.
Field::make('ip_address')->json()
Less than
El valor del campo debe ser menor que otro. Consulta la documentación de Laravel.
Field::make('newNumber')->lt('oldNumber')
Less than or equal to
El valor del campo debe ser menor o igual que otro. Consulta la documentación de Laravel.
Field::make('newNumber')->lte('oldNumber')
Mac Address
El campo debe ser una dirección MAC. Consulta la documentación de Laravel.
Field::make('mac_address')->macAddress()
Multiple Of
El campo debe ser múltiplo de un valor. Consulta la documentación de Laravel.
Field::make('number')->multipleOf(2)
Not In
El campo no debe estar incluido en la lista de valores proporcionada. Consulta la documentación de Laravel.
Field::make('status')->notIn(['cancelled', 'rejected'])
Not Regex
El campo no debe coincidir con la expresión regular dada. Consulta la documentación de Laravel.
Field::make('email')->notRegex('/^.+$/i')
Nullable
El valor del campo puede estar vacío. Esta regla se aplica por defecto si la regla required no está presente. Consulta la documentación de Laravel.
Field::make('name')->nullable()
Prohibited
El valor del campo debe estar vacío. Consulta la documentación de Laravel.
Field::make('name')->prohibited()
Prohibited If
El campo debe estar vacío solo si el otro campo especificado tiene alguno de los valores dados. Consulta la documentación de Laravel.
Field::make('name')->prohibitedIf('field', 'value')
Prohibited Unless
El campo debe estar vacío a menos que el otro campo especificado tenga alguno de los valores dados. Consulta la documentación de Laravel.
Field::make('name')->prohibitedUnless('field', 'value')
Prohibits
Si el campo no está vacío, todos los otros campos especificados deben estar vacíos. Consulta la documentación de Laravel.
Field::make('name')->prohibits('field')
Field::make('name')->prohibits(['field', 'another_field'])
Required
El valor del campo no debe estar vacío. Consulta la documentación de Laravel.
Field::make('name')->required()
Marcar un campo como requerido
Por defecto, los campos requeridos mostrarán un asterisco * junto a su etiqueta. Puedes querer ocultar el asterisco en formularios donde todos los campos son requeridos, o donde tenga sentido añadir un hint a los campos opcionales en su lugar:
use Filament\Forms\Components\TextInput;
TextInput::make('name')
->required() // Añade validación para asegurar que el campo es requerido
->markAsRequired(false) // Quita el asterisco
Si tu campo no es required(), pero aun así deseas mostrar un asterisco *, puedes usar también markAsRequired():
use Filament\Forms\Components\TextInput;
TextInput::make('name')
->markAsRequired()
Required If
El valor del campo no debe estar vacío solo si el otro campo especificado tiene alguno de los valores dados. Consulta la documentación de Laravel.
Field::make('name')->requiredIf('field', 'value')
Required If Accepted
El valor del campo no debe estar vacío solo si el otro campo especificado es igual a "yes", "on", 1, "1", true, o "true". Consulta la documentación de Laravel.
Field::make('name')->requiredIfAccepted('field')
Required Unless
El valor del campo no debe estar vacío a menos que el otro campo especificado tenga alguno de los valores dados. Consulta la documentación de Laravel.
Field::make('name')->requiredUnless('field', 'value')
Required With
El valor del campo no debe estar vacío solo si cualquiera de los otros campos especificados no está vacío. Consulta la documentación de Laravel.
Field::make('name')->requiredWith('field,another_field')
Required With All
El valor del campo no debe estar vacío solo si todos los otros campos especificados no están vacíos. Consulta la documentación de Laravel.
Field::make('name')->requiredWithAll('field,another_field')
Required Without
El valor del campo no debe estar vacío solo cuando cualquiera de los otros campos especificados esté vacío. Consulta la documentación de Laravel.
Field::make('name')->requiredWithout('field,another_field')
Required Without All
El valor del campo no debe estar vacío solo cuando todos los otros campos especificados estén vacíos. Consulta la documentación de Laravel.
Field::make('name')->requiredWithoutAll('field,another_field')
Regex
El campo debe coincidir con la expresión regular dada. Consulta la documentación de Laravel.
Field::make('email')->regex('/^.+@.+$/i')
Same
El valor del campo debe ser igual a otro. Consulta la documentación de Laravel.
Field::make('password')->same('passwordConfirmation')
Starts With
El campo debe comenzar con uno de los valores dados. Consulta la documentación de Laravel.
Field::make('name')->startsWith(['a'])
String
El campo debe ser una cadena.
Field::make('name')->string()
Unique
El valor del campo no debe existir en la base de datos. Consulta la documentación de Laravel.
Field::make('email')->unique()
Si tu formulario de Filament ya tiene un modelo Eloquent asociado, como en un recurso de panel, Filament lo usará. También puedes especificar una tabla o modelo personalizado donde buscar:
use App\Models\User;
Field::make('email')->unique(table: User::class)
Por defecto, se usará el nombre del campo como columna a buscar. Puedes especificar una columna personalizada:
Field::make('email')->unique(column: 'email_address')
Normalmente, querrás ignorar un modelo dado durante la validación de unicidad. Por ejemplo, en un formulario de "actualizar perfil" que incluye nombre, email y ubicación. Probablemente quieras verificar que el email sea único. Sin embargo, si el usuario solo cambia el nombre y no el email, no quieres un error porque ya es propietario de ese email. Si tu formulario ya tiene un modelo Eloquent asociado, como en un recurso de panel, Filament lo ignorará.
Para evitar que Filament ignore el registro Eloquent actual, puedes pasar false al parámetro ignoreRecord:
Field::make('email')->unique(ignoreRecord: false)
Alternativamente, para ignorar un registro Eloquent de tu elección, puedes pasarlo al parámetro ignorable:
Field::make('email')->unique(ignorable: $ignoredUser)
Puedes personalizar aún más la regla pasando un closure al parámetro modifyRuleUsing:
use Illuminate\Validation\Rules\Unique;
Field::make('email')
->unique(modifyRuleUsing: function (Unique $rule) {
return $rule->where('is_active', 1);
})
La regla unique de Laravel no usa el modelo Eloquent para consultar la base de datos por defecto, por lo que no aplicará ningún scope global definido en el modelo, incluidos los de soft-deletes. Por ello, incluso si existe un registro con soft-delete con el mismo valor, la validación fallará.
Dado que no se aplican scopes globales, la característica de multi-tenant de Filament tampoco delimita la consulta al tenant actual por defecto.
Para ello, debes usar el método scopedUnique(), que reemplaza la implementación unique de Laravel por una que use el modelo para consultar la base de datos, aplicando cualquier scope global definido en el modelo, incluidos soft-deletes y multi-tenant:
use Filament\Forms\Components\TextInput;
TextInput::make('email')
->scopedUnique()
Si deseas modificar la consulta Eloquent usada para comprobar la unicidad, incluido eliminar un scope global, puedes pasar una función al parámetro modifyQueryUsing:
use Filament\Forms\Components\TextInput;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
TextInput::make('email')
->scopedUnique(modifyQueryUsing: function (Builder $query) {
return $query->withoutGlobalScope(SoftDeletingScope::class);
})
ULID
El campo en validación debe ser un Identificador Universal Único y Lexicográficamente Ordenable (ULID) válido. Consulta la documentación de Laravel.
Field::make('identifier')->ulid()
UUID
El campo debe ser un identificador universal único (UUID) RFC 4122 válido (versión 1, 3, 4 o 5). Consulta la documentación de Laravel.
Field::make('identifier')->uuid()
Other rules
Puedes añadir otras reglas de validación a cualquier campo usando el método rules():
TextInput::make('slug')->rules(['alpha_dash'])
Puedes encontrar una lista completa de reglas de validación en la documentación de Laravel.
Custom rules
Puedes usar cualquier regla de validación personalizada como harías en Laravel:
TextInput::make('slug')->rules([new Uppercase()])
También puedes usar closure rules:
use Closure;
TextInput::make('slug')->rules([
fn (): Closure => function (string $attribute, $value, Closure $fail) {
if ($value === 'foo') {
$fail('The :attribute is invalid.');
}
},
])
Puedes inyectar utilidades como $get en tus reglas personalizadas, por ejemplo si necesitas referenciar otros valores del formulario. Para ello, envuelve la regla closure en otra función que la devuelva:
use Filament\Schemas\Components\Utilities\Get;
TextInput::make('slug')->rules([
fn (Get $get): Closure => function (string $attribute, $value, Closure $fail) use ($get) {
if ($get('other_field') === 'foo' && $value !== 'bar') {
$fail("The {$attribute} is invalid.");
}
},
])
Customizing validation attributes
Cuando los campos fallan la validación, su etiqueta se usa en el mensaje de error. Para personalizar la etiqueta usada en los mensajes de error, usa el método validationAttribute():
use Filament\Forms\Components\TextInput;
TextInput::make('name')
->validationAttribute('full name')
Details
Inyección de utilidades
Además de permitir un valor estático, el métodovalidationAttribute() también acepta una función para calcularlo dinámicamente. Puedes inyectar varias utilidades en la función como parámetros.Validation messages
Por defecto se usa el mensaje de error de validación de Laravel. Para personalizar los mensajes de error, usa el método validationMessages():
use Filament\Forms\Components\TextInput;
TextInput::make('email')
->unique(// ...)
->validationMessages([
'unique' => 'The :attribute has already been registered.',
])
Details
Inyección de utilidades
Además de permitir un array de valores estáticos, el métodovalidationMessages() también acepta una función por cada mensaje. Puedes inyectar varias utilidades en las funciones como parámetros.Allowing HTML in validation messages
Por defecto, los mensajes de validación se renderizan como texto plano para prevenir XSS. Sin embargo, puede que necesites renderizar HTML en los mensajes, por ejemplo al mostrar listas o enlaces. Para habilitar HTML en los mensajes de validación, usa allowHtmlValidationMessages():
use Filament\Forms\Components\TextInput;
TextInput::make('password')
->required()
->rules([
new CustomRule(), // Regla personalizada que devuelve un mensaje de validación con HTML
])
->allowHtmlValidationMessages()
Ten en cuenta que debes asegurar que el HTML de todos los mensajes de validación sea seguro de renderizar, de lo contrario tu aplicación será vulnerable a XSS.
Disabling validation when fields are not dehydrated
Cuando un campo no se deshidrata, aún se valida. Para deshabilitar la validación de campos que no se deshidratan, usa validatedWhenNotDehydrated():
use Filament\Forms\Components\TextInput;
TextInput::make('name')
->required()
->dehydrated(false)
->validatedWhenNotDehydrated(false)
Details
Inyección de utilidades
Además de permitir un valor estático, el métodovalidatedWhenNotDehydrated() también acepta una función para calcularlo dinámicamente. Puedes inyectar varias utilidades en la función como parámetros.