Skip to content

Validación

This content is not available in your language yet.

La validación es síncrona, schema-driven, traducida — funciona out-of-the-box sin que escribas un solo validador.

AJV es el validador de JSON Schema más rápido y estricto en npm. Cobalt lo configura con:

  • ajv-formats para email, date, uri, uuid, regex, etc.
  • ajv-i18n para traducir mensajes de error al locale del usuario.
  • allErrors: true para capturar TODOS los errores de un campo, no solo el primero.

Por defecto, la validación corre:

  1. 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).
  2. En cada setValue() — validación en vivo mientras el usuario escribe.
  3. En submit() — re-valida antes de emitir el evento. Si hay errores, marca todos los campos como touched para 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'
});
ValorComportamiento
'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”.

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.

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 (setValue lo 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.

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'
},
});
Validaciónenespt-BR
requiredshould 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: 8should NOT have fewer than 8 charactersdebe NO tener menos que 8 caracteresdeve NÃO ter menos que 8 caracteres
form.state.isValid // true si NO hay errores en ningún campo
form.state.isDirty // true si values !== initialValues
form.state.isSubmitting // true durante el async submit
form.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>
form.validate(); // valida todo
form.validate(['email']); // valida solo email (si tu builder lo soporta)
form.touch('email'); // marca touched (re-valida en validateOn change)
form.touchAll(); // marca todos touched

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.

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);
};

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).