# Validation
There is some cases you will want to add client side validation and showing error messages. The library will trying to make those issues easy to handle.
# Basic validation
Each field can have some rules
, a rule is a function or an object that describe which cases the field value is valid and which cases it is not.
import { Form } from 'form-wrapper-js'
import { required, email } from '@/form/validation.js'
export default {
form: Form.create({
email: {
value: null,
rules: [required, email],
},
}),
}
The field email
has 2 rules, those 2 rules are declared in another file called validation.js
.
// form/validation.js
import { isEmail } from 'some-example-library'
export const required = ({ value }) => value !== null && value !== ''
export const email = {
passes: ({ value }) => isEmail(value),
message: ({ label }) => `${label} must be an email.`,
}
there are the 2 "shapes" of validation rule:
- The first is just a function that returns a
boolean
. the error message that will be collect by the Errors collector is the default error message that has been declared in the form options - The second is an object. the object must at least have a
passes
property that should be just like a function rule. the second property ismessage
(that can be also a simplestring
), it should return an error message that will collect by the Errors collector in case the field is not valid.
TIP
By default the validation runs on submission. you can tweak out the options and make your validation runs on field input event or on field blurred event and also you can call the validation manually:
form.$validate()
- will validate the whole formform.$validate('name')
- will validate onlyname
field
check out the options before starting to use those methods.
# Validation`s functions
passes
and message
functions can be very flexible in fact you can create a very powerful validation file or files.
they are both invokes with the same arguments:
- first argument is field, which contains:
const field = {
key: 'email', // field key
label: 'Email', // label of the field
value: 'somthing@example.com', // current value of the field
}
- second argument is the whole form object
Here is a quick example for a complex validation rule:
export const sameAs = sameAsField => {
return {
passes: ({ value, label, key }, form) => value === form[sameAsField],
message: ({ value, label, key }, form) =>
`'${label}' must be equal to '${form.$labels[sameAsField]}'`,
}
}
And here is how you can use it in a Vue component.
import { Form } from 'form-wrapper-js'
import { sameAs } from '@/helpers/validation.js'
export default {
data() {
return {
form: Form.create({
password: null,
password_again: {
value: null,
rules: [sameAs('password')],
},
}),
}
},
}
The function sameAs
returns an object and that object is our validation object.
As you can see validation rules can be very powerful and you can customize it as you like.
# Promise base validation
Sometimes you will use a validation library or an http service that's returning a Promise
and not a boolean
you can use it as well by returning the Promise
in the validation function
// form/validation.js
import { RuleValidationError } from 'form-wrapper-js'
import axios from 'axios'
export const isValidEmail = async ({ value }) => {
try {
await axios.post('https://example.com/is-valid-email', { email: value })
} catch (e) {
if (e.response.status === 422) {
throw new RuleValidationError(e.response.data.message)
}
// if the error is not validation error it just handle it
// as a regular exception
throw e
}
}
As you can see passes
function will return an Promise
from the axios
library, if the promise will resolved
the field will be marked as valid, if the promise will rejected and the response status will be 422
(simple check to asset that the error is validation error and not another error),
the function will will throw RuleValidationError
, the first argument of the constructor is the validation message
WARNING
One thing to understand, you must reject with RuleValidationError
! otherwise the error will bubble up.
You can use form.$isValidating('email')
In case that your Promise
base validating take some time, the function will
return true
if the Promise
base validation is still running and false
if not.
# Dynamic validation
Dynamic validation is useful when there is a field validation that depend on another field, to solve this problem there is special library function, applyRulesIf
.
// In your vue file
import { Form, applyRulesIf } from 'form-wrapper-js'
import { required } from '@/form/validation.js'
export default {
data() {
return {
form: new Form({
is_developer: false,
programing_languages: {
value: [],
rules: [
// another rules can be here...
applyRulesIf((field, form) => form.is_developer === true, [
required,
]),
// another rules can be here...
],
},
}),
}
},
// ...Your vue stuff
}
As you can see applyRulesIf
takes 2 arguments,
- The first argument is the condition, simple function that returns boolean
- The second argument is an array of rules
In case that the condition will return true
the rules will be called in the validation process, in case that it will return false
the rules will be ignored.
# Errors
The errors collector will collect errors each time validating a specific field or the whole form,
you can display those errors out with the use of $errors
property.
<template>
<form>
<div>
<input type="text" v-model="form.email" />
<span v-if="form.$errors.has('email')">
{{ form.$errors.getFirst('email') }}
</span>
</div>
</form>
</template>
Each field have an array of errors, form.$errors.get('email')
will return the whole array,
form.$errors.getFirst('email')
will return the first error from that array.
Here is a quick snippet of some methods from the $errors
property you could and should use
from time to time.
form.$errors.any() // checks if there is any error in the form
form.$errors.has('name') // check if there is errors in the `name` field
form.$errors.clear() // will clear all the errors
form.$errors.unset('name') // will clear only `name` field errors
form.$errors.all() // will return all the fields with an array of errors for each of them.
form.$errors.fill({
name: ['some errors', 'another one'],
last_name: ['and another one again'],
}) // will fill fields errors
← Field Field Events →