Home > Net >  How to check if v-text-field has success state ( or any rule failed )?
How to check if v-text-field has success state ( or any rule failed )?

Time:01-17

I have a component holding input controls ( e.g. v-text-field ). This component provides some props, e.g. the field rules for the input. Whenever the input value passes every rule / enters the success state I want to call a function.

Given the following sample code

Reproduction link

<template>
  <v-app>
    <v-main>
      <v-text-field v-model="msg"
                    :rules="[ v => v.length > 0 || 'required' ]"
                    @update:model-value="onInput"
      />
    </v-main>
  </v-app>
</template>

<script setup>
import { ref } from 'vue'

const msg = ref('')

function onInput(newValue) {
  if(true /* text-field has success state => do things */) {
    console.log(newValue);
  }
}
</script>

How can I check if this field passed every rule? I wasn't able to find an event in the docs

I think it would be slow to run each rule function again.

CodePudding user response:

You should wrap your input with v-form component that triggers the input event with form validation state (false/true) as parameter :

<template>
  <v-app>
    <v-main>
       <v-form @update:model-value="onInput" >
         <v-text-field v-model="msg" :rules="[ v => v.length > 0 || 'required' ]"  />
      </v-form>
    </v-main>
  </v-app>
</template>

<script setup>
import { ref } from 'vue'

const msg = ref('')

function onInput(newValue) {
  if(newValue) {
    console.log('passed ',newValue);
  }
}
</script>

DEMO

CodePudding user response:

Place a ref on the element. And watch its error value:

<template>
  <v-text-field ref="input" />
</template>
<script setup>
import { ref, watch } from 'vue'

const input = ref(null)
watch(() => input.value?.error, (val) => {
  if (val) {
    // input not valid
  } else {
    // input is now valid
  }
})

See it here.

Notes:

  • uncomment <pre v-text="JSON.stringify(input, null, 2)"></pre> to see everything <v-text-field> has to offer.
  • watch is, by default, lazy. Meaning it won't be checked when the component is mounted. If you want to make this check when the component has mounted, pass a third param to it:
    { immediate: true }.
    Example.

CodePudding user response:

As you said you want to validate that on focus out event, You can do that by adding the reference to the input field and then validate that by using this syntax in your focus out event.

this.$refs.msgInput.validate()

Live Demo :

new Vue({
  vuetify: new Vuetify(),
  data: {
    msg: ''
  },
  methods: {
    validateField() {
      this.$nextTick(() => {
        if (this.$refs.msgInput.validate()) {
          console.log('validation passed')
        } else {
          console.log('validation failed')
        }
      })
    }
  }
}).$mount('#app');
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.css"/>

<div id="app">
  <v-text-field
    outline
    v-model="msg"
    label="Enter your message"
    :rules="[(v) => !!v || 'required']"
    @blur="validateField"
    ref="msgInput"
  />
</div>

Note : If you have a multiple inputs in your component, Then my suggestion would be that use v-form and attached the reference to the form. So that you can validate all the inputs in a single go on submit.

  • Related