Appearance
Rule Creation β
Use and extend any built-in rule or define your own β asynchronous rules, cross-field rules, or even required-type rules that determine whether a field must be filled.
π Defining Rules β
The defineRule() API requires a name string that is used to delcare the rules within the field. It also requires a validate() function that holds the validation logic. When not using a locale source, a default message must be supplied via message.
js
defineRule('minlength', {
validate: (value, [limit]) => {
return value.length >= limit
},
message: 'The {field} must be at least {limit} characters long.'
})π Declaring Rules β
Delcare the rule name as HTML attributes, then use it to write your own logic. The validate() function gives you access to the fieldβs value, params, and context.
html
<form>
<input type="text" name="username" value="jim" />
<input type="text" name="age" between="18,50" value="25" />
</form>The validate() function for between accepts:
valueβ25paramsβ[18,50]context:json{ "field": "username", "type": "text", "attrValue": "18,50", "form": { "username": "jim", "age": "25" } }
β‘ Built-in Rules β
The Rules offers 50+ built-in validation rules β including files, dates, multi-selects, conditional requirements, and full support for all native browser rules. Import each rule individually, import by group, or import all at once (not recommended).
js
import { defineRule } from 'suriform'
import { min, max } from 'suriform/rules'
defineRule('min', min)
defineRule('max', max)Each built-in rule are designed to be extended using object spreading. Override the message, change the format, or extend the validator however you want.
js
import { defineRule } from 'suriform'
import { min } from 'suriform/rules'
defineRule('min', {
...min,
message: 'Value must be greater than or equal to {min}.'
})π Asynchronous β
Return a simple boolean result to trigger the ruleβs default message or chain multiple conditions with nested messages to have a more dynamic messaging.
js
defineRule('username', {
validate: async (value) => {
const res = await fetch(`/api/check-username?u=${value}`)
const data = await res.json()
return data.available
},
message: 'The {field} is already taken.'
})π‘ Learn more about message resolving with the Messaging guide.
βοΈ Cross-Field β
Using the checksTarget flag, the validate() function will have access to the FormData within the context object. This allows for easy access to the target fieldβs value.
js
defineRule('match', {
validate: (value, [target], { form }) => {
return value == form[target]
},
checksTarget: true,
message: 'Fields do not match.'
})html
<form>
<input type="text" name="foo" match="bar" />
<input type="text" name="bar" />
</form>π‘ Combine cross-field logic with async rules for complex validation scenarios.
β Required-Type β
With the checksRequired flag, the system registers the rule in a different registry that runs an additional isFieldRequired() check, dedicated to required-type rules.
js
defineRule('required-with', {
validate: (_, [target], { form }) => {
if (!target) return false
return !!form[target]
},
checksTarget: true,
checksRequired: true
})html
<form>
<input type="text" name="foo" required-with="bar" />
<input type="text" name="bar" />
</form>π‘ Learn more about validation flow with the validateForm() API.
