Vee-validate: Confirmed rule not working on custom component

Created on 4 Mar 2019  路  10Comments  路  Source: logaretm/vee-validate

Versions

  • vee-validate: 2.1.7
  • vue: 2.5.22

Describe the bug
Confirmed rule not working on custom component, _again_.

Your advice

You should add ref to the target Field. And prefix the confirmed field name with $, so it would look like this: v-validate="'required|confirmed:$password'" This is because Vue components cannot be selected by the DOM API so we use refs instead. There are a couple of duplicate issues like this one.

works in 2.0.6 version, but doesn't work now in 2.1.7.

Demo link
For example, the same sandbox but I added 芦ref禄 and updated vee-validate to 2.1.7

馃摎 docs

Most helpful comment

@ntraykov Its fine, this is one of the most confusing subjects with vee-validate because of the many changes ocurred.

Your example is missing the ctor config, which is needed if you are using components as your inputs, this is documented here

To explain this, vee-validate knows how to find native input values, for example input.value would yield the value for most inputs. For custom components, this is not the case as there is not a standard implementation for them. So you need to help vee-validate by telling it how it can fetch the value, by adding $_veeValidate object to your component config you can apply useful options listed in the docs link I provided which will allow you to be more flexible in your components.

Here is an updated example:

https://codesandbox.io/s/9l7r2mlxwy

All 10 comments

I have found the confirmed rule does not work properly in 2.1.7 also using the validationProvider component. No matter what I try I always get the error in console (Error in render: "TypeError: Cannot read property '$watch' of undefined") when validationProvider is using a confirmed rule. Even the example sandboxes in the docs didn't work properly after adding a confirmed rule to the form so I'm not sure where to turn with this error.

@dreit-p @jeissler I had a similar issue this morning and fixed it using the vid. For some reason, this matches on the vid instead of the ref when using a ValidationProvider. It's not documented very well though.

There is an example of it working on this example: https://codesandbox.io/s/yw8yrmn9y9 in the refactoredform.vue file, where the two password fields are used.

Or, without wrapped components is below. Note the vid on the first provider and the confirmed rule on the second provider.

<ValidationProvider rules="required" name="Password" vid="password">
        <b-form-group 
          slot-scope="{ valid, errors }">      
            <b-form-input
              type="password"
              v-model="password"
              :state="errors[0] ? false : (valid ? true : null)">
            </b-form-input>
        </b-form-group>
      </ValidationProvider>

      <ValidationProvider rules="required|confirmed:password" name="Password confirmation">
        <b-form-group 
          slot-scope="{ valid, errors }">
            <b-form-input
              type="password"
              v-model="confirmation"
              :state="errors[0] ? false : (valid ? true : null)">
            </b-form-input>
        </b-form-group>
      </ValidationProvider>

@DM2489 Thanks very much for posting this. You are correct and I'm glad you took the time to help out :) So in my case the confirmed (using validationProvider) does work w/o error now once I get the vid component BEFORE the confirmed rule AND are using the ValidationObserver component as well. In different scenarios I was goofing both of those things separately and the demos above made my errors clear. Thanks again!

@dreit-p Some issues were outdated so my advice there is no longer applicable. You should always refer to the docs for the latest documented behavior.

The cross-field validation has been changed to use the target param without any prefixes, so you only need to remove the $ character from your target param. The cross-field validation with the v-validate directive now only uses refs to find fields, no other selectors are supported.

Like @DM2489 mentioned, validation providers are easier in that regard as they do not have scope limitations like directives, you can cross-validate a field in another component given they have the same observer. But they use vid prop to identify and locate fields since refs do not carry outside a component scope.

I am sorry for bothering you for that as well, but it is not working on my side as well. I know I've had to put a ref attribute and then put it in the target on the confirmed rule, but still, this is not working. Could you please help.

Here is my code: https://codesandbox.io/s/j1zv5v9jv9?fontsize=14

@ntraykov Its fine, this is one of the most confusing subjects with vee-validate because of the many changes ocurred.

Your example is missing the ctor config, which is needed if you are using components as your inputs, this is documented here

To explain this, vee-validate knows how to find native input values, for example input.value would yield the value for most inputs. For custom components, this is not the case as there is not a standard implementation for them. So you need to help vee-validate by telling it how it can fetch the value, by adding $_veeValidate object to your component config you can apply useful options listed in the docs link I provided which will allow you to be more flexible in your components.

Here is an updated example:

https://codesandbox.io/s/9l7r2mlxwy

Thank you so much! Great work! Very well created and rich in functionallity plugin!

Just to give you some feedback - this part of the documentation has confused me, that's why I wasn't able to do it myself:

Custom components that act as an input typically use the v-model to communicate its value, VeeValidate tries to watch the model using $watch API which has its limitations. For instance it cannot watch a v-for iterator value since it does not exist on the Vue instance per say, it only exists in the v-for loop context.

VeeValidate falls back to watching the value prop for that custom component. If your component customizes the model constructor property, VeeValidate will detect the correct prop name and validate watch that instead.

From the first paragraph I understood that if I put v-model on my custom component, vee validate will $watch this v-model. But if there is no v-model it will fall back to value prop. So in my case I've added v-model and was surprised it doesn't work. From my point of view, I've did everything properly as described.

This covers most cases, except the case where your component does not use v-model to pass its current value. You can further improve VeeValidate integration with your component using the ctor options explained in the following section, which gives you a fine control over the validation behavior of your component

From the third paragraph, I understood that if I don't put v-model on my component, I need to use ctor. Since I use v-model, I skipped the ctor step.

Then, from the documentation of the confirmed rule, it says I have to just put a ref attribute and put the ref's value of the attribute as a target of the confirmed rule.

I did everything as described. It appears I'm not.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

YamenSharaf picture YamenSharaf  路  3Comments

schel4ok picture schel4ok  路  3Comments

parweb picture parweb  路  3Comments

the94air picture the94air  路  3Comments

ash0080 picture ash0080  路  3Comments