Validation rules
Rules are how a form decides whether a value is acceptable. You attach them to a field as an array. Each rule is an object with an r key naming the rule:
{ "name": "email", "type": "text", "label": "Email", "rules": [{ "r": "required" }, { "r": "email" }]}Rules run in order on the server. A field with no rules accepts anything (subject to the global size limits).
Rules that take a parameter
Section titled “Rules that take a parameter”Some rules need a value, written after a colon inside the r string:
{ "r": "min:3" }{ "r": "max:2000" }{ "r": "in:Sales,Support,Other" }{ "r": "regex:/^[A-Z]{2}\\d{4}$/" }Built-in rules
Section titled “Built-in rules”| Rule | Checks | Example |
|---|---|---|
required |
The field is not empty. On a checkbox it means “must be ticked”. On a file field it means “a file was uploaded”. | { "r": "required" } |
email |
A valid email address. | { "r": "email" } |
min:N |
The text is at least N characters long. With numeric or integer on the field, the number is at least N. |
{ "r": "min:10" } |
max:N |
The text is at most N characters long. With numeric or integer on the field, the number is at most N. |
{ "r": "max:500" } |
numeric |
The value is a number. | { "r": "numeric" } |
integer |
The value is a whole number. | { "r": "integer" } |
date |
A real date in YYYY-MM-DD format. |
{ "r": "date" } |
url |
A valid URL. | { "r": "url" } |
tel |
A loose international phone number: 6 to 15 digits, common separators and a leading + allowed. |
{ "r": "tel" } |
regex:pattern |
The value matches your regular expression. The pattern is taken literally, and a pattern that does not work is refused when you save. | { "r": "regex:/^[A-Z]{2}\\d{4}$/" } |
in:a,b,c |
The value is one of the listed options. | { "r": "in:S,M,L,XL" } |
minChecked:N |
A checkbox group has at least N boxes ticked. Only for checkboxes. |
{ "r": "minChecked:2" } |
maxChecked:N |
A checkbox group has at most N boxes ticked. Only for checkboxes. |
{ "r": "maxChecked:3" } |
Length or number: what min and max compare
Section titled “Length or number: what min and max compare”min and max count characters on most fields. When the field also has a numeric or integer rule, they compare the number itself instead. An age field is the usual example:
{ "name": "age", "type": "number", "label": "How old are you?", "rules": [{ "r": "numeric" }, { "r": "min:18" }, { "r": "max:120" }]}This field accepts 18, 42 and 18,5, and refuses 17 and 150. Without the numeric rule the same min:18 would ask for at least 18 characters. The field type does not change this. A number field with no numeric or integer rule still counts characters.
A few details:
- The number is compared only when the answer really is a number. If it is not, the
numericorintegerrule reports it, andminandmaxfall back to counting characters. - A decimal comma typed into a
numberfield becomes a dot before the rules run, so18,5is compared as 18.5. - On a numeric field N is any number, so
min:-10andmax:2.5work as written. On a length N is a whole number of 0 or more. Anything else is refused when you save. - The default messages say “This value is too small.” and “This value is too large.” instead of “too short” and “too long”.
- On a text field,
max:Nalso lets the answer be longer than the usual 5000 characters. On a numeric field it does not, because there N is a number, not a length.
Polish rules
Section titled “Polish rules”For Polish sites, three extra rules are built in:
| Rule | Checks |
|---|---|
telPL |
A Polish phone number (9 digits, also accepts landline numbers). Stricter than tel. |
nip |
A valid Polish NIP (tax identification number), including its checksum. |
postCodePL |
A Polish postal code in NN-NNN format. |
Use telPL instead of the loose tel rule when the site serves one country. Use tel when visitors could be anywhere.
Rules for file fields
Section titled “Rules for file fields”File fields take their own rules. See Field types for the file field itself.
| Rule | Checks |
|---|---|
mimes:ext,ext |
The file’s real type (detected from its contents) is in this list. Example: mimes:pdf,jpg,png. |
maxSize:MB |
The file is no larger than this many megabytes. There is also a hard 10 MB cap regardless of this rule. |
maxFiles:N |
At most N files. Currently one file per field is supported. |
What happens before the rules run
Section titled “What happens before the rules run”Every submitted value is cleaned before a single rule looks at it, and what the rules see is what gets stored, emailed and sent to your webhooks.
Cleaning means HTML is removed. A message typed as I need <b>10</b> units is stored as I need 10 units. Line breaks in a textarea are kept, because a message without them would arrive as one long paragraph. Checkboxes are left alone, since they already accept only a fixed set of values, and uploaded files are described by the server, never by the browser.
An email field is a special case worth knowing about. If someone types an address with a space in it, OctaForms does not quietly delete the space and send the lead to whoever owns the resulting address. The value stays as typed, the email rule rejects it, and the visitor is asked to correct it.
Error messages
Section titled “Error messages”If a value fails a rule, OctaForms returns a message for that rule. You do not have to write any messages: leave the rule as { "r": "..." } and a clear, translated default is used automatically. This is the recommended approach, because the default follows the site’s language.
To override a message for a specific rule, add an m key:
{ "r": "required", "m": "Please tell us your name so we can reply." }Errors come back grouped by field and then by rule, so your form can show each message next to the field it belongs to. The exact shape is in Your own JavaScript; the JS helper places them for you.
Adding your own rule
Section titled “Adding your own rule”You can register custom rules with a filter. See Custom validation rules.