Skip to content
Advertisement

How do I access another field using vuelidate

I’m making some validators on a form for shipping using vuelidate. Currently I’m checcking if the postalCode is in the right format. This field is dependent on the country field though (because different countries have different postal code formats. I’m having trouble accessing the viewmodel itself though, and I don’t get the explanation in vuelidates docs.

Currently I’m working with the following redacted code:

import Vue from 'vue';
import {validationMixin} from 'vuelidate';
import {required} from 'vuelidate/lib/validators';
import {getEuMembers} from 'is-eu-member';
import countries from 'i18n-iso-countries';
import postalCodes from 'postal-codes-js';
new Vue({
  el: '#app',
  mixins: [shoppingBagMixin, validationMixin],
  data: {
    form: {
      country: {},
      postalCode: '',
      // more data...
    },
  },
  validations: {
    form: {
      $each: {required},
      country: {
      },
      postalCode: {
// ----------- The following 3 lines are problematic ----------
        validPostalCode: (value) => { 
          if (!this.country || !this.country.code) return false; 
          return postalCodes.validate(this.country.code, value);
        },
      },
    },
  },
methods: {
    euCountries: euCountries,
    async onSubmit(event) {
      this.$v.$touch();
      if (this.$v.$invalid) {
        return false; // TODO: Show error
      }

      // Sending data using fetch()

      return false;
    },
  },
});

/**
 * Returns a list of EU country codes and translated names
 * @param {String} lang Language to translate the country name to.
 * Needs to be a code such as 'nl' or 'en'
 * @return {Array} Array of {code: ISOCode, name: name} objects
 */
function euCountries(lang) {
  countries.registerLocale(require(`i18n-iso-countries/langs/${lang}.json`));
  return getEuMembers().map((ISOCode) => {
    const name = countries.getName(ISOCode, lang, {});
    return {code: ISOCode, name: name};
  });
}

for completeness, a snippet of the form:

<fieldset>
  <legend>Adres:</legend>
  <label for="country">Land:</label>
  <select id="country" name="country" v-model="form.country" type="text">
    <option v-once v-for="country in euCountries('nl')" :value="country">{{country.name}}</option>
  </select>
  <label for="postalCode">Postcode:</label>
  <input id="postalCode" name="postalCode" v-model="form.postalCode" type="text">
</fieldset>

Advertisement

Answer

this context may be in use in some cases (not in this one). but it obviously isn’t available as component instance inside arrow function.

As the documentation shows, component instance is available in custom validator as the second parameter:

validPostalCode: (value, vm) => { 
  // vm.country 
  ...

This applies to Vuelidate 0.x and doesn’t work the same way with 2.x and composition API.

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement