Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom input not working with yup.ref() #4753

Closed
2 of 5 tasks
blevinelrp opened this issue May 23, 2024 · 2 comments
Closed
2 of 5 tasks

Custom input not working with yup.ref() #4753

blevinelrp opened this issue May 23, 2024 · 2 comments
Labels
✨ enhancement a "nice to have" feature

Comments

@blevinelrp
Copy link

blevinelrp commented May 23, 2024

Form has 2 fields in the schema (goal is validate confirmPassword with password...make sure they match).

config gets passed in as prop to component.

config = {
        rows: [
          {
            name: 'password',
            rules: yup.string().required().min(6).label('Password')
          },
          {
             name: 'confirmPassword',
             rules: yup
              .string()
             .oneOf([yup.ref('password')], 'Passwords must match')
             .required()
             .label('Confirm Password')
           }
]}

In the component

// build validationSchema

const validationSchema = {}
props.config.rows.forEach((row) => {
    row.forEach((field) => {
        validationSchema[field.name] = field.rules
    }
)})

create form context

const { defineField, handleSubmit, resetForm, errors, values } = useForm({
  validationSchema: validationSchema
})

// build models for custom components

const fieldName2model = {}
props.config.rows.forEach((row) => {
    row.forEach((field) => {
        const [model] = defineField(field.name)
        fieldName2model[field.name] = model
    }
)})

loop through and create custom comp

<div v-for="row in props.config.rows" class="row">
<div v-for="field in row" class="col">
    <div class="field">
        <label :for="field.name">{{field.label}}</label>
        <InputText
            :name="field.name"
            v-model="fieldName2model[field.name].value"
            :class="{ 'p-invalid': errors[field.name]}"
        />
        <small class="p-error">
            {{ errors[field.name] }}
        </small>
    </div>
</div>

values if typing in "aaaaaaa" into both input fields
{ "password": "aaaaaaa", "confirmPassword": "aaaaaaa" }

errors:
{ "confirmPassword": "Passwords must match" }

Reproduction steps

No response

Version

Vue.js 3.x and vee-validate 4.x

What browsers are you seeing the problem on?

  • Firefox
  • Chrome
  • Safari
  • Microsoft Edge

Relevant log output

No response

Demo link

na

Code of Conduct

@logaretm
Copy link
Owner

logaretm commented May 28, 2024

field-level validation doesn't work with yup.ref as the reference doesn't exist unless it is a form-level schema with yup.object.

I think vee-validate could try to instead expose them as context for yup parser as it cannot override or provide refs to yup. You would reference other fields with yup.ref('$password') the $ is important here as per their docs.

I will work on this and publish a minor release with it.

EDIT: Implemented in 27fe5c8

@catalin-bratu
Copy link

catalin-bratu commented Aug 9, 2024

@logaretm

I'm sorry for commenting on a closed ticket.

With the new changes shouldn't this also work for when the schema is passed directly to the Form component?

https://vee-validate.logaretm.com/v4/examples/cross-field-validation/

<Form @submit="onSubmit" :validation-schema="schema">

const schema = yup.object().shape({
  password: yup.string().min(5).required(),
  passwordConfirmation: yup
    .string()
    .required()
    .oneOf([yup.ref('$password')], 'Passwords do not match'),
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
✨ enhancement a "nice to have" feature
Projects
None yet
Development

No branches or pull requests

3 participants