Skip to content

Validation

Forms are validated on the server with the CodeIgniter validation. The rules are derived from the field definitions; you only add what the field cannot know.

TextInput::make('personnel_number')->required()->maxLength(30)->rules('alpha_dash'),
// required|string|max_length[30]|alpha_dash
TextInput::make('email')->email()->required()->rules('is_unique[contacts.email]'),
NumberInput::make('discount')->decimals(1)->min(0)->max(100),
// permit_empty|localized_number[1]|localized_min[0]|localized_max[100]

Every field’s rules are, in this order:

  1. required (with required()) or permit_empty,
  2. the rules of the field type, see below,
  3. the rules added with rules().

rules() takes one or more rules; strings separated by | are split: rules('alpha_dash', 'min_length[3]') and rules('alpha_dash|min_length[3]') are the same. All rules of CodeIgniter and of Anvil can be used, as well as own rule sets registered in Config\Validation.

Fields with several values validate their items as well, as nested rules with a * path: permissions.* of a CheckboxList, keywords.* of a TagsInput, line_items.*.product of a Repeater.

Field Rules
TextInput string, max_length[n], min_length[n]; by type valid_email, valid_url_strict[https,http], numeric or integer instead of string
Textarea, MarkdownEditor string, max_length[n]
NumberInput localized_number[decimals], localized_min[…], localized_max[…]
Select, Radio in_list[…] of the options
CheckboxList is_array; items in_list[…]
Toggle in_list[0,1] (always optional)
DateInput valid_date[Y-m-d] / valid_date[Y-m-d\TH:i]
BelongsTo, UserSelect in_list[…] of the selectable UUIDs; searchable: valid_uuid plus a scoped lookup when saving
TagsInput is_array, max_count[n]; items string, max_length[n]
Repeater is_array, max_count[n], min_count[n]; the rules of the sub fields per row; with lookup() valid_uuid per row and a check against the source when saving
FileUpload type, size and content are checked when the file is stored; required() when saving
PasswordInput string, max_byte[72]

Anvil registers these rules in addition to the ones of CodeIgniter (Anvil\Validation\AnvilRules, messages in English and German):

Rule Passes when
valid_uuid the value is a UUID
localized_number[d] the value is a number in the format of the current locale with at most d decimals
localized_min[n], localized_max[n] the locale number is at least / at most n
min_count[n], max_count[n] the list has at least / at most n entries
values_in_list[a,b] every value of a list (or comma separated text) is one of the given ones
  • Input that has no rule never reaches the model. The saved data is built from the fields that are writable in the current operation, not from the request. A client cannot write tenant_id, uuid or any other column that is not part of the form, even if it is in $allowedFields.
  • Disabled fields (disabled(), disabledOn()) and hidden fields (hiddenOn(), fields in hidden layouts) are neither validated nor written, so a manipulated request cannot change them.
  • After validation each field converts its input (trimming, locale numbers, UUID to id, JSON for lists).
  • Validation rules of the model ($validationRules) apply in addition when the record is saved. Rules about other records (e.g. “the end date is after the start date”) belong into the model or into data rules.

Errors are answered with HTTP 422 and shown below the fields, with the label of the field in the message (“Line items: Product” for a sub field of a repeater). If the field is in a collapsed section, another tab or another wizard step, the form opens it and focuses the field, see Errors in hidden parts.

required() also sets the required attribute of the input and a red asterisk at the label; the browser check is only a convenience, the server validates every request.

Messages come from the language files of CodeIgniter and Anvil and use the label of the field. Override them in app/Language/<locale>/Validation.php like any CodeIgniter message. Action dialogs and the API use the same rules and messages.