Skip to content

Commit

Permalink
docs: move some sections around and add guide for the 'reasoning' feat
Browse files Browse the repository at this point in the history
  • Loading branch information
logaretm committed Sep 13, 2019
1 parent 3b202fd commit 135a44a
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 107 deletions.
55 changes: 52 additions & 3 deletions docs/guide/advanced-validation.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,55 @@

Previously you learned how to add validation rules to vee-validate, in this guide you will learn how to use the full API to create more powerful and complex rules.

## Dynamic Messages

Some rules can be really complicated, and as such you need to provide suitable feedback for your users. While you cannot provide multiple messages for your rules, you can leverage the fact that messages can be functions. Meaning you could create a dynamic message for your rules, allowing you to be more flexible.

```js{4}
import { extend } from 'vee-validate';
extend('someRule', {
message: (field, values) => `The current timestamp is ${Date.now()}`
});
```

The previous example isn't very useful, but it showcases how dynamic the messages can be. Earlier you learned that the `values` object [contains some useful information](./displaying-errors.md#message-function) about the field and the rule. It can also contain arbitrary data that you can return from your rule's `validate` function.

Consider this dummy `profanity` rule where we have 2 states for the error message:

```js
import { extend } from 'vee-validate';

extend('profanity', {
validate: value => {
if (value === 'heck') {
return { valid: false, data: { reason: 'NICE_H_TRY' } };
}

if (value === 'frick') {
return { valid: false, data: { reason: 'NICE_F_TRY' } };
}

return true;
},
message: (field, values) => {
if (values.reason === 'NICE_H_TRY') {
return 'You cannot say any of the H words.';
}

if (values.reason === 'NICE_F_TRY') {
return 'You cannot say any of the F words.';
}

return 'You cannot say that.';
}
});
```

The `data` property returned in the `validate` function result is an object that contains additional information that we want to pass to our message generator function. The contents of the `data` prop will be merged with the `values` passed to the message function, allowing you to craft specific error messages for specific reasons.

You can find this example [live right here](https://codesandbox.io/embed/veevalidate-30-dynamic-messages-3k649).

## Cross-Field validation

Some rules validity are dependent on other fields values, a rule like `confirmed` will need access to another field's value and compare it with the current one to be able to determine validity.
Expand Down Expand Up @@ -151,9 +200,9 @@ Assuming you have a rule that sends a request to an endpoint, you might want to
```js{2}
extend('lazyRule', {
lazy: true,
validate: (value) => {
validate: value => {
// Some stuff.
},
}
});
```

Expand Down Expand Up @@ -195,7 +244,7 @@ This would work fine for most cases but in complex rules, this starts to break d
Params can have a slightly richer schema to allow you to convert types before passing them to your `validate` function, instead of defining an array of param names, we define an array of objects:

```js{21,25}
function toDate (value) {
function toDate(value) {
// handle timestamps
if (typeof value === 'number') {
return new Date(value);
Expand Down
1 change: 1 addition & 0 deletions docs/guide/basic-validation.md
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ There are more to rules, but for now you know how to use most common cases in yo
- Cross-Field validation (confirm password).
- Required State Rules.
- Backend messages.
- Dynamic Error Messages.

You can refer to the [Advanced Validation](./advanced-validation.md) guide for these cases.

Expand Down
116 changes: 87 additions & 29 deletions docs/guide/displaying-errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,7 @@ Typically you would want to display one error at a time for your fields, which i
You will notice that only 1 error is generated. this is because vee-validate tries to be efficient by stopping validation on the first failure it encounters for any rule. to disable this behavior and force the validation to test against all rules you can provide `bails` prop set to `false` on the `ValidationProvider`.

```vue{4}
<ValidationProvider
rules="required|min:3|alpha"
v-slot="{ errors }"
:bails="false"
>
<ValidationProvider rules="required|min:3|alpha" v-slot="{ errors }" :bails="false">
<input v-model="value" type="text">
<ul>
<li v-for="error in errors">{{ error }}</li>
Expand All @@ -40,7 +36,7 @@ configure({ bails: false });
```

:::tip
The `bails` prop takes precedence over the global config, that means you can have fields with either behavior at the same time in your app by passing a `bails` prop explicitly to those fields.
The `bails` prop takes precedence over the global config, that means you can have fields with either behavior at the same time in your app by passing a `bails` prop explicitly to those fields.
:::

Now that we've setup multiple errors generation properly, you can iterate over the `errors` array to display them with `v-for`:
Expand All @@ -57,10 +53,10 @@ Now that we've setup multiple errors generation properly, you can iterate over t
You can check it out in this sample:

<StyledProvider
rules="required|min:3|alpha"
v-slot="{ errors }"
:bails="false"
>
rules="required|min:3|alpha"
v-slot="{ errors }"
:bails="false">

<input v-model="values.multiple" type="text" placeholder="type something">
<ul>
<li v-for="error in errors">{{ error }}</li>
Expand Down Expand Up @@ -92,10 +88,9 @@ Consider this **optional field**:
Even though the field is configured with `bails` set to `false`, it will still skip the field (consider it valid) if it has empty value. You can test this in the previous sample, fill it with a value and clear it and it will still hold the errors.

<StyledProvider
rules="min:3|numeric"
v-slot="{ errors }"
:bails="false"
>
rules="min:3|numeric"
v-slot="{ errors }"
:bails="false">
<input v-model="values.multiple" type="text" placeholder="type something">
<ul>
<li v-for="error in errors">{{ error }}</li>
Expand All @@ -105,12 +100,7 @@ Even though the field is configured with `bails` set to `false`, it will still s
Now this might not be what you want, you may need to run all rules regardless of the field requirement status. While this is rare, you could still disable this behavior by setting `skipIfEmpty` prop to false.

```vue{2,3}
<ValidationProvider
rules="min:3|numeric"
:skipIfEmpty="false"
:bails="false"
v-slot="{ errors }"
>
<ValidationProvider rules="min:3|numeric" :skipIfEmpty="false" :bails="false" v-slot="{ errors }">
<input v-model="value" type="text">
<ul>
<li v-for="error in errors">{{ error }}</li>
Expand Down Expand Up @@ -139,29 +129,97 @@ You can configure this behavior globally, by setting `skipOptional` config value
So far you only saw `{_field_}` placeholder used in the error messages to refer to the field, you can change that by specifying a `name` prop on the `ValidationProvider`.

```vue{2}
<ValidationProvider
name="first name"
rules="required|min:2"
v-slot="{ errors }"
<ValidationProvider name="first name" rules="required|min:2" v-slot="{ errors }">
<input v-model="value" type="text">
<span>{{ errors[0] }}</span>
</ValidationProvider>
```

<StyledProvider
rules="required|min:2"
name="first name"
v-slot="{ errors }"
>
<input v-model="values.name" type="text" placeholder="type something...">
<span>{{ errors[0] }}</span>
</StyledProvider>
## Messages Format

Validation messages in vee-validate can either be a `string` or a function that returns a string for more complex messages.

### String Interpolation

String messages can be plain like:

```
This field is required.
```

Or it can be a **template string** like this:

```
The {_field_} is required.
```

Template messages are interpolated before display to replace the placeholders, placeholders are surrounded by `{placeholder}`. You can use the rule's parameter names as placeholders.

For example consider this rule:

```js
import { extend } from 'vee-validate';

extend('lengthBetween', {
validate: (value, { min, max }) => {
const length = value && value.length;

return length >= min && length <= max;
},
params: ['min', 'max'],
message: 'The {_field_} length must be between {min} and {max}'
});
```

```vue
<ValidationProvider name="code" rules="required|lengthBetween:3,6" v-slot="{ errors }">
<input v-model="value" type="text">
<span>{{ errors[0] }}</span>
</ValidationProvider>
```

<StyledProvider
rules="required|min:2"
name="first name"
name="code"
rules="required|lengthBetween:3,6"
v-slot="{ errors }"
>
<input v-model="values.name" type="text" placeholder="type something...">
<input v-model="values.template" type="text" placeholder="Type something...">
<span>{{ errors[0] }}</span>
</StyledProvider>
:::tip Advanced Customization
You can localize your messages and display custom messages for specific fields with the [localization API](./localization.md).
:::tip Parameter Names
You can use any names for your placeholders, except for:

- `{_field_}` which is the field name.
- `{_value_}` which is the field value.
- `{_rule_}` which is the rule name.

Which are provided internally.
:::

### Message Function

Messages can be a function as well, giving you more flexibility over your messages. The function signature looks like this:

```ts
interface ValidationMessageGenerator {
(field: string, values?: Record<string, any>): string;
}
```

The `field` is the field name, the `values` argument is an object containing the placeholder values used in string interpolation. Meaning it will contain `_value_`, `_field_` and `_rule_` values as well as any other params previously declared.

You can use this feature to create dynamic messages for your rules which is helpful for [providing multiple reasons for failing a rule](./advanced-validation.md#dynamic-messages), or [localization](./localization.md).

---

Now that we have got grasp of the basics, we can learn more about the validation provider.
Expand Down
76 changes: 1 addition & 75 deletions docs/guide/localization.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,80 +6,6 @@ VeeValidate has built-in localization support for validation messages which is o
In `2.x`, vee-validate used to ship with localization enabled and pre-configured, this has been changed in `3.x` to allow for a more flexible i18n system.
:::

## Messages Format

Validation messages in vee-validate can either be a `string` or a function that returns a string for more complex messages.

### String Interpolation

String messages can be plain like:

```
This field is required.
```

Or it can be a **template string** like this:

```
The {_field_} is required.
```

Template messages are interpolated before display to replace the placeholders, placeholders are surrounded by `{placeholder}`. You can use the rule's parameter names as placeholders as well as props you return in `data` prop in the validation response.

For example consider this rule:

```js
import { extend } from 'vee-validate';

extend('lengthBetween', {
validate: (value, { min, max }) => {
const length = value && value.length;

return length >= min && length <= max;
},
params: ['min', 'max'],
message: 'The {_field_} length must be between {min} and {max}'
});
```

```vue
<ValidationProvider name="code" rules="required|lengthBetween:3,6" v-slot="{ errors }">
<input v-model="value" type="text">
<span>{{ errors[0] }}</span>
</ValidationProvider>
```

<StyledProvider
name="code"
rules="required|lengthBetween:3,6"
v-slot="{ errors }"
>
<input v-model="values.template" type="text" placeholder="Type something...">
<span>{{ errors[0] }}</span>
</StyledProvider>
:::tip Parameter Names
You can use any names for your placeholders, except for:

- `{_field_}` which is the field name.
- `{_value_}` which is the field value.
- `{_rule_}` which is the rule name.

Which are provided internally.
:::

### Message Function

Messages can be a function as well, giving you more flexibility over your messages. The function signature looks like this:

```ts
interface ValidationMessageGenerator {
(field: string, values?: Record<string, any>): string;
}
```

The `field` is the field name, the `values` argument is an object containing the placeholder values used in string interpolation. Meaning it will contain `_value_`, `_field_` and `_rule_` values as well as any other params previously declared.

## i18n

vee-validate has over 40+ locales available for the shipped validations, but they are not install by default as they have a large overhead so you need to import the locales you need.
Expand Down Expand Up @@ -115,7 +41,7 @@ By default you cannot import JSON files in TypeScript, so be sure to add those o
"compilerOptions": {
// ...
"resolveJsonModule": true,
"esModuleInterop": true,
"esModuleInterop": true
// ...
}
}
Expand Down

0 comments on commit 135a44a

Please sign in to comment.