Vee-validate and yup with dynamic input fields not validating and showing errors

215 Views Asked by At

As a follow up question to my post here. I actually have fields in a loop so I need to setup vee-validate and yup dynamically.

So here's my script:

import { useForm } from 'vee-validate'
import * as yup from 'yup'

const {
  values,
  errors,
  defineComponentBinds,
  isSubmitting,
  setFieldValue,
  handleSubmit
} = useForm({
  validationSchema: yup.object({
    moduleValidationInputs: yup.object(moduleValidationSchemes.value)
  })
})

const moduleValidationSchemes = ref({})
const moduleValidationInputs = ref({})

onMounted(() => {
  newModuleFields.value.map(nmf => {
    if (nmf.rules && nmf.rules.required) {
      moduleValidationSchemes.value[nmf.uniqueName] = yup.string().label(nmf.label).required()
    } else moduleValidationSchemes.value[nmf.uniqueName] = yup.string().label(nmf.label).nullable()

    moduleValidationInputs.value[nmf.uniqueName] = defineComponentBinds(`moduleValidationInputs.${nmf.uniqueName}`)
  })
})

and my template:

<div v-for="(requiredField, rfx) in requiredFields" :key="rfx" class="col-6">
  <p>{{ errors }}</p>
  <span class="p-float-label">
    <InputText
     v-bind="moduleValidationInputs[requiredField.uniqueName]"
     class="w-full border-left-3 border-red-600"
    />
    <label>{{ requiredField.label }}</label>
  </span>
</div>

I just replicate the way the static fields I setup in the previous post, but I don't know why it's not showing any errors. It's like it's not validating the dynamic fields.

UPDATE:

I tested changing this line:

moduleValidationInputs: yup.object(moduleValidationSchemes.value)

Into this:

moduleValidationInputs: yup.object({
  lead_company: yup.string().label('Company').required()
})

And it works. .

It seems that useForm from vee-validate don't like generating dynamic yup.object to populate validationSchema.

Or am I doing it wrong?

1

There are 1 best solutions below

0
Lekz Flores On BEST ANSWER

Ended up using validateSync with setFieldError to handle error catching.

const validateSyncFunc = handleSubmit((values, actions) => {
  // update errors
  Object.keys(moduleValidationInputs.value).forEach((key, index) => {
    const val = moduleValidationInputs.value[key].modelValue
    if (val !== null) setFieldError(key, null)
  })

  try {
    moduleValidationSchemes.value.validateSync(values, { abortEarly: false })
    return values
  } catch (error) {
    let errArray = []
    error.inner.map(err => {
      let obj = { [err.path]: err.message }
      errArray.push(obj)
      // actions.setErrors(obj)
      actions.setFieldError(err.path, err.message)
    })

    return error
  }
})