Tengo 2 menús desplegables en cada fila y puedo agregar y eliminar dinámicamente filas aparte de la primera. Me gustaría enviar el formulario si solo hay una fila (presentada desde el principio) y está vacía y no puedo enviarla si:
o
Estoy usando la validación yup.
He intentado verificar la longitud con .test(), pero esta prueba se ejecuta siempre después de marcar 'requerido'.
Esto es lo que me gustaría tener:
const validationSchema = yup.object({ values: yup.array() .of( yup.object({ value1: yup.string().required(), // ONLY IF ARRAY LENGTH > 1 value2: yup.string().required()// ONLY IF VALUE1 IS SELECTED }) )});Si te entiendo correctamente, entonces esto debería funcionar.
const mySchema = yup.object({ values: yup.array().of( yup.object({ value1: yup .string() .test( "test-1", "error: required if array length > 1", (value, context) => { const [, values] = context.from; const { value: { values: arrayValues } } = values; // ONLY IF ARRAY LENGTH > 1 if (arrayValues.length > 1) { // valid only if value is provided return !!value; } } ), value2: yup.string().when("value1", { // if value1 is provied, value2 should be provided too is: (value1) => !!value1, then: (value2) => value2.required() }) }) ) }); // should pass console.log( mySchema.validateSync({ values: [ { value1: "1", value2: "2" }, { value1: "1", value2: "2" } ] }) ); // ValidationError: error: required if array length > 1 console.log( mySchema.validateSync({ values: [{ value1: "1", value2: "2" }, { value2: "2" }] }) ); // ValidationError: values[1].value2 is a required field console.log( mySchema.validateSync({ values: [{ value1: "1", value2: "2" }, { value1: "1" }] }) ); La clave aquí es eliminar .required() y proporcionar su propio check in test() cuando la matriz cumpla con su condición personalizada.
para acceder al valor principal dentro de .test() , use context.from
const [parent1, parent2, ...rest] = context.from;