Abel
Abel

Reputation: 1614

How do I dynamically set validations fields in vuelidate

I'm using VueJS2 with vuelidate library. I can validate the fields based on the validation objects. The validation will execute during computed time. But My validations objects is fixed, instead of dynamic. I have some fields will hide based on the selection.

import { validationMixin } from 'vuelidate'
import { required, maxLength, email } from 'vuelidate/lib/validators'

export default {
mixins: [validationMixin],
validations: {
  company_name: { required },
  company_position_title: { required }
},
methods: {
  submit(){
    this.$v.touch();
    if(this.$v.$invalid == false){ 
      // All validation fields success
    }
  }
}
}

HTML

<v-select
  label="Who are you?"
  v-model="select" // can be 'company' or 'others'
  :items="items"
  :error-messages="selectErrors"
  @change="$v.select.$touch();resetInfoFields();"
  @blur="$v.select.$touch()"
  required
></v-select>

<v-text-field
  label="Company Name"
  v-model="company_name"
  :error-messages="companyNameErrors"
  :counter="150"
  @input="$v.companyName.$touch()"
  @blur="$v.companyName.$touch()"
  v-show="select == 'Company'"
></v-text-field>

<v-text-field
  label="Company Position Title"
  v-model="company_position_title"
  :error-messages="companyPositionErrors"
  :counter="150"
  @input="$v.companyPosition.$touch()"
  @blur="$v.companyPosition.$touch()"
  v-show="select == 'Company'"
></v-text-field>

<v-btn @click="submit">submit</v-btn>

Problem

When I select 'other' option and click submit, the this.$v.$invalid is still true. It should be false as there is no validation fields required. When I select 'company', that two fields must required and validated.

Upvotes: 15

Views: 27721

Answers (3)

Boern
Boern

Reputation: 7752

Here's how it's done with Vue3 + composition API according to the docu.

const state = reactive({
  shippingAddress: '',
  billingSameAsShipping: false,
  billingAddress: ''
})
const rules = computed(() => {
  const localRules = {
    shippingAddress: { required }
  }
  if (!state.billingSameAsShipping) {
    // if billing is not the same as shipping, require it
    localRules.billingAddress = {
      required
    }
  }
  return localRules
})
const v$ = useVuelidate(rules, state)

Upvotes: 2

Maske
Maske

Reputation: 864

you need a dynamic validation schema

validations () {
  if (!this.select === 'company') {
    return {
      company_name: { required },
      company_position_title: { required }
    }
  }
}

More info: Dynamic validation schema

Upvotes: 16

Daltom
Daltom

Reputation: 71

Another way is using requiredIf

itemtocheck: {
  requiredIf: requiredIf(function () {
    return this.myitem !== 'somevalue'
  }),
  minLength: minLength(2) },

Upvotes: 7

Related Questions