Validación
La validación es síncrona, schema-driven, traducida — funciona out-of-the-box sin que escribas un solo validador.
Motor: AJV 8
Sección titulada «Motor: AJV 8»AJV es el validador de JSON Schema más rápido y estricto en npm. Cobalt lo configura con:
ajv-formatsparaemail,date,uri,uuid,regex, etc.ajv-i18npara traducir mensajes de error al locale del usuario.allErrors: truepara capturar TODOS los errores de un campo, no solo el primero.
Cuándo se valida
Sección titulada «Cuándo se valida»Por defecto, la validación corre:
- En la construcción del form — para que el state inicial refleje si el form es válido o no (útil para deshabilitar el submit desde el inicio).
- En cada
setValue()— validación en vivo mientras el usuario escribe. - En
submit()— re-valida antes de emitir el evento. Si hay errores, marca todos los campos comotouchedpara que el usuario vea todos los mensajes a la vez.
Puedes cambiar este comportamiento con la opción validateOn:
const form = createForm({ schema: { modelSchema, locale: 'es' }, validateOn: 'blur', // 'change' | 'blur' | 'submit'});| Valor | Comportamiento |
|---|---|
'change' (default) | Valida en cada setValue. UI en vivo. |
'blur' | Valida solo cuando el campo pierde foco. Menos ruido para forms largos. |
'submit' | Solo valida en submit(). Modo “old school”. |
Errores
Sección titulada «Errores»El state expone errors como Record<string, string[]>:
{ email: ['debe coincidir con el formato "email"'], password: [ 'debe NO tener menos que 8 caracteres', 'debe coincidir con el patrón "^(?=...)"', ],}Un campo puede tener varios errores (por eso es array). La UI por defecto muestra solo el primero, pero puedes acceder a todos.
Errores solo en campos “touched”
Sección titulada «Errores solo en campos “touched”»Para evitar mostrar errores antes de que el usuario interactúe, la UI por defecto solo muestra errores de campos touched. Un campo se marca touched cuando:
- El usuario lo modifica (
setValuelo marca touched) - El campo pierde foco
- El form intenta hacer submit (
touchAll())
Si quieres mostrar todos los errores sin esperar, llama form.touchAll() al inicio.
Locales
Sección titulada «Locales»ajv-i18n viene con traducciones para 30+ idiomas. Cobalt configura por defecto es, en, pt-BR:
const form = createForm({ schema: { modelSchema: userSchema, locale: 'es', // 'es' | 'en' | 'pt-BR' },});Ejemplos de mensajes traducidos
Sección titulada «Ejemplos de mensajes traducidos»| Validación | en | es | pt-BR |
|---|---|---|---|
required | should have required property ’…‘ | debe tener la propiedad requerida ’…‘ | deve ter a propriedade obrigatória ’…’ |
format: 'email' | should match format “email” | debe coincidir con el formato “email” | deve corresponder ao formato “email” |
minLength: 8 | should NOT have fewer than 8 characters | debe NO tener menos que 8 caracteres | deve NÃO ter menos que 8 caracteres |
Estado de validez
Sección titulada «Estado de validez»form.state.isValid // true si NO hay errores en ningún campoform.state.isDirty // true si values !== initialValuesform.state.isSubmitting // true durante el async submitform.state.touched // Record<string, boolean>Útil para deshabilitar el botón submit:
<template> <CoFormRenderer :form="form"> <template #footer> <co-button label="Guardar" variant="primary" :disabled="!form.isValid.value || form.isSubmitting.value" @click="form.submit" /> </template> </CoFormRenderer></template>Validación de campos individuales
Sección titulada «Validación de campos individuales»form.validate(); // valida todoform.validate(['email']); // valida solo email (si tu builder lo soporta)form.touch('email'); // marca touched (re-valida en validateOn change)form.touchAll(); // marca todos touchedCustom validators
Sección titulada «Custom validators»El form-core trabaja con cualquier schema que cumpla la interfaz FormSchemaLike:
interface FormSchemaLike { fields: string[]; properties: Record<string, any>; validator?: { validate(data): boolean; errors: AjvError[] }; validateField?(name, value, data): string[]; // ...}Para casos complejos (validación async contra backend, reglas cross-field), registra un builder custom:
import { configureFormSchemaBuilder, FormSchemaWeb } from '@prolibu-suite/cobalt-form-core';
configureFormSchemaBuilder(async (modelSchema, locale) => { // FormSchemaWeb es el builder completo de Prolibu (de @skemify/cases) // Soporta validación async, reglas custom, hooks de transformación return new FormSchemaWeb({ modelSchema, locale });});A partir de ese momento, todos los createForm() usan ese builder.
Validación cross-field (manual)
Sección titulada «Validación cross-field (manual)»Para reglas como “password debe coincidir con confirmPassword”, lo más simple es validar manualmente antes de submit:
const onSubmit = async (e) => { if (form.values.value.password !== form.values.value.confirmPassword) { form.setError('confirmPassword', ['Las contraseñas no coinciden']); return; } await api.signup(form.values.value);};Acceso bajo del API
Sección titulada «Acceso bajo del API»Para casos avanzados puedes invocar AJV directamente:
import { createInlineValidator } from '@prolibu-suite/cobalt-form-core';
const schema = createInlineValidator(modelSchema, 'es');const isValid = schema.validator.validate(data);console.log(schema.validator.errors);// → AJV error objects (con keyword, schemaPath, instancePath, message, params)Útil para validar fuera de un form (ej. en una API route).