Behaviour
Validation
Forms use Laravel's validation on the server, and check the simple rules in the browser as well.
Rules on a field are Laravel rules. They run on the server every time, and errors land on the right field, even inside tabs and repeater rows.
TextInput::make('email')->email()->required()->unique(ignoreRecord: true);
Dedicated rules
Most rules have a method. Here are the common ones.
| Kind | Methods |
|---|---|
| Presence | required(), nullable(), filled(), requiredIf(), requiredUnless(), requiredWith(), requiredWithAll(), requiredWithout(), requiredWithoutAll(), requiredIfAccepted() |
| Prohibited | prohibited(), prohibitedIf(), prohibitedUnless(), prohibits() |
| Format | string(), alpha(), alphaDash(), alphaNum(), ascii(), json(), uuid(), ulid(), ip(), ipv4(), ipv6(), macAddress(), hexColor(), activeUrl(), regex(), notRegex(), multipleOf(), enum() |
| Text | startsWith(), endsWith(), doesntStartWith(), doesntEndWith() |
| Comparing | same(), different(), confirmed(), gt(), gte(), lt(), lte(), in(), notIn() |
| Dates | after(), afterOrEqual(), before(), beforeOrEqual() |
| Database | exists(), unique(), scopedExists(), scopedUnique() |
Any other rule
rules() adds Laravel rules, and rule() adds one, with an optional condition.
TextInput::make('code')->rules(['digits:6']);
TextInput::make('vat')->rule('required', fn (Get $get): bool => $get('type') === 'business');
A closure rule works too.
use Closure;
TextInput::make('slug')->rules([
fn () => function (string $attribute, mixed $value, Closure $fail): void {
if ($value === 'admin') {
$fail('That name is taken.');
}
},
]);
Database rules
unique() and exists() take the record into account.
TextInput::make('email')->unique(ignoreRecord: true);
Select::make('owner_id')->exists('users', 'id');
Global scopes don't apply to them. scopedUnique() and scopedExists() go through the model's query, so its scopes do.
Confirming a value
confirmed() needs a field named {name}_confirmation next to it.
TextInput::make('password')->password()->confirmed();
TextInput::make('password_confirmation')->password()->saved(false);
Messages
validationMessages() sets errors by rule name, and validationAttribute() sets what they call the field.
TextInput::make('recipient')
->required()
->validationAttribute('recipient name')
->validationMessages(['required' => 'Who is this for?']);
Checking in the browser
frontendValidation() on a form checks the simple rules before calling the server: required, length, ranges and formats.
OrderForm::make()->frontendValidation()->toSchema();
liveValidation() on a field checks its rules on the server as soon as it changes, which suits something like an email that must be unique.
TextInput::make('email')->unique()->liveValidation();