Vee-validate: Flags not working

Created on 12 Sep 2017  ยท  10Comments  ยท  Source: logaretm/vee-validate

Versions:

  • VueJs: 2.4.2
  • Vee-Validate: 2.0.0-rc.14

Description:

Only the flags valid or invalid actually change. I am using the API method so none of the fields are using the inline html approach, everything is set in the component itself.

I followed the example under Validator API and the validation works as expected but watching the flags / fields in the Dev Tools or simply displaying them in the html page with a <pre>{{ flags }}</pre>
Only the 2 fields change. I can type, preset data values, clear the inputs or the form and everything else stays the same

dirty:false
invalid:false
pending:false
pristine:true
required:true
touched:false
untouched:true
valid:true
validated:true

Steps To Reproduce:

Component bits:

 <v-text-field 
   v-model="formData.email"
   label="Email" 
   name="formData.email"
    :error-messages="errors.collect('formData.email')"
    :append-icon="setIcon(flags, 'formData.email')">
</v-text-field>

Even tried using the standard method I see everywhere:

isFormDirty: function () {
      return Object.keys(this.flags).some(key => this.flags[key].dirty)
},

watch:

watch: {
    'formData.email' (value) {
      this.validator.validate('formData.email', value)
    }
},

I used flags vs fields for the fieldBag, everything was working fine using 2.0.0-beta-17 but after upgrade the flags/fields no longer change except valid / invalid

Any help would be greatly appreciated.
Thanks,
Dave

โ” question

Most helpful comment

You are getting multiple states because of your use of some instead of every, depending on the flag meaning you may choose to use every over some. It is more like:

every => all
some => any

For example these are the correct uses from my point of view:

{
    // form is dirty when if any field is dirty, so using 'some' is correct.
    isFormDirty() {
      return Object.keys(this.fields).some(key => this.fields[key].dirty);
    },
    // form is pristine when all inputs are pristine, so using 'every' is more suitable.
    isFormPristine() {
      return Object.keys(this.fields).every(key => this.fields[key].pristine);
    },
    // form is valid when all inputs are valid.
    isFormValid() {
      return Object.keys(this.fields).every(key => this.fields[key].valid);
    },
     // form is invalid when any field is invalid.
    isFormInvalid() {
      return Object.keys(this.fields).some(key => this.fields[key].invalid);
    },
    // form is touched when any field is touched.
    isFormTouched() {
      return Object.keys(this.fields).some(key => this.fields[key].touched);
    },
    // form is untouched when all fields are untouched.
    isFormUntouched() {
      return Object.keys(this.fields).every(key => this.fields[key].untouched);
    }
}

Anyways after fixing those flags, they seem to work fine to me.

All 10 comments

Hey Dave, Fields that are added manually do not have the full features of a field that uses the directive, for the small reason that it does not have access to the input source like the textbox or selectbox or whatever, so most flags cannot be determined only: pending, valid, invalid.

You can use the directive if you want:

 <v-text-field 
   v-model="formData.email"
   label="Email" 
   name="formData.email"
    v-validate="'required|email'"
    :error-messages="errors.collect('formData.email')"
    :append-icon="setIcon(flags, 'formData.email')">
</v-text-field>

And the flags should be working if the component emits the appropriate events.

Hi,

i have the same issue but I am using the directive:

<b-form-input
  type="text"
  class="form-control"
  id="temperature"
  name="temperature"
  v-model="temperature"
  v-validate="'required|decimal|min_value:10|max_value:40'"
  :state="!errors.has('temperature')"
></b-form-input>
<span class="form-text text-muted" v-show="errors.has('temperature')">@{{ errors.first('temperature') }}</span>
<span v-show="fields.temperature && fields.temperature.dirty">I'm Dirty</span>
<span v-show="fields.temperature && fields.temperature.pristine">I'm Pristine</span>
<span v-show="fields.temperature && fields.temperature.touched">I'm touched</span>
<span v-show="fields.temperature && fields.temperature.untouched">I'm untouched</span>
<span v-show="fields.temperature && fields.temperature.valid">I'm valid</span>
<span v-show="fields.temperature && fields.temperature.invalid">I'm invalid</span>

I am using Bootstrap4Vue here.

The field remains "untouched" even it had the focus or I insert something.

Update:
I have these methods:

            isFormDirty() {
                return Object.keys(this.fields).some(key => this.fields[key].dirty);
            },
            isFormPristine() {
                return Object.keys(this.fields).some(key => this.fields[key].pristine);
            },
            isFormValid() {
                return Object.keys(this.fields).some(key => this.fields[key].valid);
            },
            isFormInvalid() {
                return Object.keys(this.fields).some(key => this.fields[key].invalid);
            },
            isFormTouched() {
                return Object.keys(this.fields).some(key => this.fields[key].touched);
            },
            isFormUntouched() {
                return Object.keys(this.fields).some(key => this.fields[key].untouched);
            },

and added this HTML to the page (inline-template)

<span v-show="isFormDirty">Form is dirty</span><br>
<span v-show="isFormPristine">Form is pristine</span><br>
<span v-show="isFormValid">Form is valid</span><br>
<span v-show="isFormInvalid">Form is invalid</span><br>
<span v-show="isFormUntouched">Form is untouched</span><br>
<span v-show="isFormTouched">Form is touched</span><br>

The only flag which seems to update is dirty. All others are show no state change.

@Konafets hello, does your components emit the correct events?

for example the touched and untouched flags require the component to emit blur event, as for the valid flags they should be working fine. Try to reproduce the issue in a fiddle if you can.

Hi @logaretm,

Here is the JSBin: http://jsbin.com/najoqev/edit?html,js,console,output


  1. Inital state:
    Form is untouched

When I type some text in a field, I expect that the whole form is marked as touched. But the form is in two states now; touched and untouched.


  1. Inital state:
    Form is pristine

When I type some text in a field, I expect that the whole form is marked as dirty. But the form is in two states now; pristine and dirty.


  1. Inital state:
    invalid: null, valid: null

When I type some valid text in a field, forms gets valid state. When I additionally insert some invalid text eg. 90 in temperature, I expect that the whole form is marked as invalid. But the form is in two states now; valid and invalid.

I see you are using rc.7 in your example, we are at rc.18 at the moment, can you update and test if the issue is still there?

Oh, sorry. I got that from link from the documentation.

However, updating to latest version did not fixed it.

You are getting multiple states because of your use of some instead of every, depending on the flag meaning you may choose to use every over some. It is more like:

every => all
some => any

For example these are the correct uses from my point of view:

{
    // form is dirty when if any field is dirty, so using 'some' is correct.
    isFormDirty() {
      return Object.keys(this.fields).some(key => this.fields[key].dirty);
    },
    // form is pristine when all inputs are pristine, so using 'every' is more suitable.
    isFormPristine() {
      return Object.keys(this.fields).every(key => this.fields[key].pristine);
    },
    // form is valid when all inputs are valid.
    isFormValid() {
      return Object.keys(this.fields).every(key => this.fields[key].valid);
    },
     // form is invalid when any field is invalid.
    isFormInvalid() {
      return Object.keys(this.fields).some(key => this.fields[key].invalid);
    },
    // form is touched when any field is touched.
    isFormTouched() {
      return Object.keys(this.fields).some(key => this.fields[key].touched);
    },
    // form is untouched when all fields are untouched.
    isFormUntouched() {
      return Object.keys(this.fields).every(key => this.fields[key].untouched);
    }
}

Anyways after fixing those flags, they seem to work fine to me.

Haha, I just figured that out. Have a look at the updated bin. Thanks for the help, tough.

Maybe add this to the documentation.

Thanks for your example @logaretm

Is there a reason why these computed properties, i.e. isFormValid, aren't properties of fields or $validator, since a lot of ppl are adding this code manually?

@nicokoenig totally agree here! any update?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

the94air picture the94air  ยท  3Comments

Etheryte picture Etheryte  ยท  3Comments

7immer picture 7immer  ยท  3Comments

HunterJS-bit picture HunterJS-bit  ยท  3Comments

MaxMilton picture MaxMilton  ยท  3Comments