Validators
Adding validators to your Control Fields
Section titled “Adding validators to your Control Fields”Validators provide contextual messages for errors in Control Fields.
A Validator can validate different types of data, and each Validator will have a set of validations. For example, a String Validator will be able to check the length of a string, meanwhile a Number Validator can check the maximum or minimum value. You can also create custom Validators, please check the section Creating a custom Validator to know more.
Let’s create a password input with a required Validator. Just add a validator property to a Control Field as shown below:
{ "form": [ { "uid": "userPasswordInput", "kind": "control", "widget": "textinput", "path": "user.password", "validator": { "type": "string", "required": true } } ]}You can add more validators, triggering multiple errors if one or more of the requirements are not fulfilled. Let’s add validations for minimum length 8 characters, maximum length 20 characters and a pattern to check that the password has only letters and numbers.
{ "form": [ { "uid": "userPasswordInput", "kind": "control", "widget": "textinput", "path": "user.password", "validator": { "type": "string", "required": true, "minLength": 8, "maxLength": 20, "pattern": "^(?=.*[A-Za-z])(?=.*\\d)[A-Za-z\\d]+$" } } ]}Let’s give it a try!
Creating a custom validator
Section titled “Creating a custom validator”To create custom validators, implement functions that follow the CustomValidatorSchemaFn interface. For example, let’s create a validator that allows us to enter only certain names:
export const allowedNames: CustomValidatorSchemaFn = (names: string[]) => z.string().check( z.superRefine((val, ctx) => { if (val && names.includes(val) === false) { ctx.addIssue({ code: 'custom', message: `Name "${val}" not in ${names.map((name) => `"${name}"`).join(', ')}`, input: val, }); } }), );Next, inform the form that it should use the custom validator when it encounters a specific key in the validator declaration within your JSON. To do this, create a CustomValidatorSchemas object and pass it to the form through its customValidators input.
import * as Core from '@golemui/core';import { allowedNames } from './custom-validators/allowed-names';
const customValidators: Core.CustomValidatorSchemas = { allowedNames,};
export function FormPage() { return ( <div> <React.FormComponent (...) customValidators={customValidators} /> </div> );}import * as Core from '@golemui/core';import { allowedNames } from './custom-validators/allowed-names';
@Component({ selector: 'my-form-app', template: `<gui-form (...) [customValidators]="customValidators"> </gui-form> `,})class MyFormApp { protected customValidators: Core.CustomValidatorSchemas = { allowedNames, };}import * as Core from '@golemui/core';import { allowedNames } from './custom-validators/allowed-names';
@customElement('lit-form')export class FormElement extends LitElement { protected customValidators: Core.CustomValidatorSchemas = { allowedNames, };
render() { return html` <gui-form (...) .customValidators=${this.customValidators} ></gui-form> `; }}Finally, declare your validator:
{ { kind: 'control', widget: 'textinput', path: 'user.name', validator: { type: 'custom', allowedNames: ['John', 'Jane'] } },}Type something different from John and Jane to trigger the validation error.
Configuring when validation triggers
Section titled “Configuring when validation triggers”To allow users to define when field validation should run, set the validateOn: ValidateOn property at the form level.
type ValidateOn = | 'eager' | 'change' | 'blur' | 'submit' | ('change' | 'blur' | 'submit')[];When not set, the default validateOn behaviour is 'eager'.
ValidateOn behaviour
Section titled “ValidateOn behaviour”'change': When the user interacts with the field and changes its value.'blur': When the user has interacted with the field and leaves the field.'submit': When using ‘submit’, validation triggers when the ‘submit’ event is emitted. When that happens, all fields are also touched first.
{ widget: 'button', label: 'Create User', on: { click: 'submit', },}'eager': Validates when any of the above happens.
import * as Core from '@golemui/core';
export function FormPage() { return ( <div> <React.FormComponent (...) validateOn="change" /> </div> );}import * as Core from '@golemui/core';
@Component({ selector: 'my-form-app', template: `<gui-form (...) [validateOn]="validateOn"> </gui-form> `,})class MyFormApp { protected validateOn: Core.ValidateOn = 'change';}import * as Core from '@golemui/core';
@customElement('lit-form')export class FormElement extends LitElement { protected validateOn: Core.ValidateOn = 'change';
render() { return html` <gui-form (...) .validateOn=${this.validateOn} ></gui-form> `; }}