1
votes

Take a look at the official Vuetify form validation example.

The very first example, if you click in a field and then outside it, it is automatically validated. The entire field becomes red and you get a hint in red text.

What I would like is based on that built-in/native validation to add or remove a class (that turns the text red) on a completely separate HTML element.

It would be ideal if something like hint-for="" exists. Some way to connect a separate HTML element with the form field validation.

I have tried to condition the class with the "valid" property of the form element, something like this: this.$refs.form.$children[1].valid but this doesn't exist on page load and throws errors.

Right now I have some results by basically having double validation, the normal one that validates automatically based on the "rules" property on the form field, and a custom one that I call my self on @input and on @blur of the form field, but this is largely inefficient so I'm hoping there's a better way.

2

2 Answers

0
votes

You can use the value of the v-form to track the validity of your form. In order to listen to changes you can use the input event like this

<template>
  <div>
    <v-form lazy-validation v-model="valid" @input="updateOtherElement">
      <v-text-field
        v-model="email"
        :rules="emailRules"
        label="Email"
        required
      ></v-text-field>
    </v-form>
  </div>
</template>

<script>
  export default {
    data () {
      return {
      valid: true,
      email: "",
      emailRules: [
          v => /.+@.+/.test(v) || 'E-mail must be valid',
        ],
      }
    },
    methods: {
      updateOtherElement(valid) {
        // update other elements css
      }
    }
  }
</script>

An alternative would be to track the changes with a watcher

0
votes

This is what I came up with.

I had some trouble with validation being active immediately and nonexistent text fields on page load but with this setup, it works.

So once validation kicks in the fields will turn red by the native Vuetify validation if they are not valid, and I toggle the "invalid" class on a completely separate piece of HTML with custom functions. What is important here that each text field has it's own "subheader" which will turn red only if that single connected text-filed is invalid, not the entire form.

<template>
    <v-form
    ref="form"
    lazy-validation
    >
        <v-subheader v-bind:class="passwordValid()">
            Password *
        </v-subheader>
        <v-text-field
        :rules="rules.password"
        ref="password"
        ></v-text-field>
        <v-subheader v-bind:class="passwordAgainValid()">
            Password Again *
        </v-subheader>
        <v-text-field
        :rules="rules.passwordAgain"
        ref="passwordAgain"
        ></v-text-field>
    </v-form>
    <v-btn
    v-on:click="save"
    >
        Save
    </v-btn>
</template>
<script>
    export default {
        methods: {
            save() {
                let self = this
                self.activateRules()
                self.$nextTick(function () {
                    if (self.$refs.form.validate()) {
                        self.rules = {}
                        // submit...
                    }
                })
            },
            activateRules () {
                this.rules = {
                    password: [
                        v => v.length > 0 || ''
                    ],
                    passwordAgain: [
                        v => v.length > 0 || ''
                    ]
                }
            },
            passwordValid: function () {
                let passwordValid = true
                if (this.$refs.password) {
                    passwordValid = this.$refs.password.valid
                }
                return {
                    'error--text': !passwordValid
                }
            },
            passwordAgainValid: function () {
                let passwordAgainValid = true
                if (this.$refs.passwordAgain) {
                    passwordAgainValid = this.$refs.passwordAgain.valid
                }
                return {
                    'error--text': !passwordAgainValid
                }
            }
        }
    }
</script>