[//]: # 'AUTO INSERT HEADER PREPUBLISH'
# Validation examples
## Required Validator
The required validator can be put onto every form field element and will make sure that element is
not empty.
For an input that may mean that it is not an empty string,
while for a checkbox group it means at least one checkbox needs to be checked.
```js script
import { html } from '@lion/core';
/* eslint-disable import/no-extraneous-dependencies */
import { LionInput } from '@lion/input';
import '@lion/checkbox-group/lion-checkbox-group.js';
import '@lion/checkbox-group/lion-checkbox.js';
import '@lion/combobox/lion-combobox.js';
import '@lion/fieldset/lion-fieldset.js';
import '@lion/form/lion-form.js';
import '@lion/input-amount/lion-input-amount.js';
import '@lion/input-date/lion-input-date.js';
import '@lion/input-datepicker/lion-input-datepicker.js';
import '@lion/input-email/lion-input-email.js';
import '@lion/input-iban/lion-input-iban.js';
import '@lion/input-range/lion-input-range.js';
import '@lion/input-stepper/lion-input-stepper.js';
import '@lion/input/lion-input.js';
import '@lion/listbox/lion-listbox.js';
import '@lion/listbox/lion-option.js';
import '@lion/listbox/lion-options.js';
import '@lion/radio-group/lion-radio-group.js';
import '@lion/radio-group/lion-radio.js';
import '@lion/select/lion-select.js';
import '@lion/select-rich/lion-select-rich.js';
import '@lion/textarea/lion-textarea.js';
import {
DefaultSuccess,
EqualsLength,
IsDate,
IsEmail,
IsNumber,
MaxDate,
MaxLength,
MaxNumber,
MinDate,
MinLength,
MinMaxDate,
MinMaxLength,
MinMaxNumber,
MinNumber,
Required,
Validator,
Pattern,
} from '@lion/form-core';
import { localize } from '@lion/localize';
import { loadDefaultFeedbackMessages } from '@lion/validate-messages';
export default {
title: 'Forms/Validation/Examples',
};
loadDefaultFeedbackMessages();
```
```js preview-story
export const requiredValidator = () => html`
`;
```
## String Validators
Useful on input elements it allows to define how many characters can be entered.
```js preview-story
export const stringValidators = () => html`
Rocks" is in this input #LionRocks'}
label="Pattern"
>
`;
```
## Number Validators
Number validations assume that it's modelValue is actually a number.
Therefore it may only be used on input that have an appropriate parser/formatter like the input-amount.
```js preview-story
export const numberValidators = () => html`
`;
```
## Date Validators
Date validators work with real javascript dates. Use them on input-date.
```js preview-story
export const dateValidators = () => {
const today = new Date();
const year = today.getFullYear();
const month = today.getMonth();
const day = today.getDate();
const yesterday = new Date(year, month, day - 1);
const tomorrow = new Date(year, month, day + 1);
return html`
`;
};
```
## Email Validator
```js preview-story
export const emailValidator = () => html`
`;
```
## Checkbox Validator
You can apply validation to the ``, similar to how you would do so in any fieldset.
The interaction states of the `` are evaluated in order to hide or show feedback messages.
```js preview-story
export const checkboxValidation = () => {
const validate = () => {
const checkboxGroup = document.querySelector('#scientists');
checkboxGroup.submitted = !checkboxGroup.submitted;
};
return html`
`;
};
```
Below is a more advanced validator on the group that evaluates the children checkboxes' checked states.
```js preview-story
export const checkboxValidationAdvanced = () => {
class HasMinTwoChecked extends Validator {
execute(value) {
return value.length < 2;
}
static get validatorName() {
return 'HasMinTwoChecked';
}
static async getMessage() {
return 'You need to select at least 2 values.';
}
}
const validate = () => {
const checkboxGroup = document.querySelector('#scientists2');
checkboxGroup.submitted = !checkboxGroup.submitted;
};
return html`
`;
};
```
## Radio Validator
```js preview-story
export const radioValidation = () => {
const validate = () => {
const radioGroup = document.querySelector('#dinos');
radioGroup.submitted = !radioGroup.submitted;
};
return html`
`;
};
```
You can also create a validator that validates whether a certain option is checked.
```js preview-story
export const radioValidationAdvanced = () => {
class IsBrontosaurus extends Validator {
static get validatorName() {
return 'IsBrontosaurus';
}
execute(value) {
let showFeedback = false;
if (value !== 'brontosaurus') {
showFeedback = true;
}
return showFeedback;
}
static async getMessage() {
return 'You need to select "brontosaurus"';
}
}
const validate = () => {
const radioGroup = document.querySelector('#dinosTwo');
radioGroup.submitted = !radioGroup.submitted;
};
return html`
`;
};
```
## Combobox
Validation can be used as normal, below is an example of a combobox with a `Required` validator.
```js preview-story
export const validationCombobox = () => {
Required.getMessage = () => 'Please enter a value';
return html`
RockyRocky IIRocky IIIRocky IVRocky VRocky Balboa
`;
};
```
## Validation Types
When defining your own component you can decide to allow for multiple types of validation.
By default only `error` is used, however there are certainly use cases where warning or success messages make sense.
```js preview-story
export const validationTypes = () => {
try {
class MyTypesInput extends LionInput {
static get validationTypes() {
return ['error', 'warning', 'info', 'success'];
}
}
customElements.define('my-types-input', MyTypesInput);
} catch (err) {
// expected as it is a demo
}
return html`
`;
};
```
## Custom Validators
Here is an example how you can make your own validator and providing the error messages directly within.
You can even hard code localization in there if needed or you can use a localization system.
```js preview-story
export const customValidators = () => {
class MyValidator extends Validator {
static get validatorName() {
return 'myValidator';
}
execute(modelValue, param) {
return modelValue !== param;
}
static getMessage({ fieldName, modelValue, params: param }) {
if (modelValue.length >= param.length - 1 && param.startsWith(modelValue)) {
return 'Almost there...';
}
return `No "${param}" found in ${fieldName}`;
}
}
return html`
`;
};
```
## Default messages
To get default validation messages you need to import and call the `loadDefaultFeedbackMessages` function once in your application.
Sometimes the default messages don't make sense for your input field. In that case you want to override it by adding a `getMessage` function to your validator.
```js preview-story
export const defaultMessages = () => html`
`;
```
## Override fieldName
In the scenario that the default messages are correct, but you only want to change the `fieldName`, this can both be done for a single specific validator or for all at once.
```js preview-story
export const overrideFieldName = () => html`
`;
```
## Asynchronous validation
```js preview-story
export const asynchronousValidation = () => {
function pause(ms = 0) {
return new Promise(resolve => {
setTimeout(() => {
resolve();
}, ms);
});
}
class AsyncValidator extends Validator {
constructor(...args) {
super(...args);
}
static get validatorName() {
return 'asyncValidator';
}
static get async() {
return true;
}
async execute() {
console.log('async pending...');
await pause(2000);
console.log('async done...');
return true;
}
static getMessage({ modelValue }) {
return `validated for modelValue: ${modelValue}...`;
}
}
return html`
`;
};
```
## Dynamic parameter change
```js preview-story
export const dynamicParameterChange = () => {
const beginDate = new Date('09/09/1990');
const minDateValidatorRef = new MinDate(beginDate, {
message: 'Fill in a date after your birth date',
});
return html`
{
if (!errorState) {
// Since graduation date is usually not before birth date
minDateValidatorRef.param = modelValue;
}
}}"
>
`;
};
```
## Disabled inputs validation
According to the W3C specs, Disabled fields should not be validated.
Therefor if the attribute disabled is present on a lion-input it will not be validated.
```js preview-story
export const disabledInputsValidation = () => html`
`;
```
### Form Validation Reset
```js preview-story
export const FormValidationReset = () => html`
`;
```