Validation of form inputs does not occur during typing, only when the input is blurred

Currently, I have implemented a combobox with input data validation using Vuelidate:

<template>
    <v-combobox
        clearable
        v-model="surname"
        :items="commonSurnames"
        label="Surname"
        placeholder="Type in the surname"
        class="pt-5 pb-5"
        :error-messages="surnameErrors"
        @input="$v.surname.$touch()"
        @blur="$v.surname.$touch()">
    </v-combobox>
</template>

<script>
import { validationMixin } from 'vuelidate'
import { required, maxLength } from 'vuelidate/lib/validators'

export default {
    mixins: [validationMixin],
    validations: {
        surname: {
            required,
            maxLength: maxLength(30),
            validSurname(surname) {
                return (
                    /^[a-zA-Z]-?*.+$/.test(surname)
                )
            }
        },
    name: 'Surnames',

    data() {
        return {
            surname: '',
            [...]
    },
    methods: {
        [...]
    },
    computed: {
        surnameErrors() {
            const errors = []
            if (!this.$v.surname.$dirty) return errors
            !this.$v.surname.validSurname && errors.push('Format must be like: Smith or Smith-Wesson')
            !this.$v.surname.maxLength && errors.push('Surname must be at most 30 characters long.')
            !this.$v.surname.required && errors.push('Surname is required.')
            return errors
    }
}
</script>

Versions of components:

  "dependencies": {
    "@vue/compiler-sfc": "^3.0.0",
    "core-js": "^3.6.5",
    "vue": "^2.6.11",
    "vuelidate": "^0.7.5",
    "vuetify": "^2.2.11"
  },

After following the instructions outlined in the Vuetify Documentation, I noticed that my form validation behaves slightly differently. For instance, I am able to exceed the 30-character limit without any notification while typing. The same goes for RegEx validation, where any value is accepted without an error until I leave the input field. Could I have missed something during the copying of the example from the docs, or is there an issue with how the @input listener functions? Perhaps, v-combobox cannot be validated in this manner?

Answer №1

v-combobox triggers change or input events only when a valid value is selected from the dropdown. The text inputted in the combobox serves as a search query to find a valid value, and this input is linked to the v-combobox's search-input property.

Referencing the v-combobox documentation, you can see that update:search-input event is triggered when the search input changes. This event can be utilized to connect to the validation handler:

<!-- ORIGINAL: -->
<v-combobox @input="$v.surname.$touch()">

<!-- MODIFIED: -->
<v-combobox @update:search-input="$v.surname.$touch()">

Answer №2

Previously, I utilized a component wrapper that encapsulated v-combobox, v-autocomplete, and v-select (all in one multi-functional wrapper). My suggestion is to use the provided code within a wrapper to avoid the hassle of copying and pasting the fix/workaround.

In order to implement the workaround, it was necessary to delve into the Vuetify sources. This involved manipulating the errorBucket and valid properties within the @update:search-input listener.

Furthermore, emitting 'input' may be required. A minor adjustment is needed to prevent the propagation into the v-combobox value, as it could disrupt the autocomplete functionality. Thus, the code snippet if (this.search) { return; }

For a complete example, you can check out the following link: Codepen

Vue.component(
  'my-combobox', {
  template: `
      <v-combobox
         ref="combobox"
         outlined dense
         v-model="selection"
         v-bind="{ ...$attrs, items, rules: validationRules }"
         v-on="$listeners"
         @update:search-input="onSearch"
         @focus="touched = true"></v-combobox>
      `,
  props: {
    value: String,
    items: Array,
    required: Boolean,
    rules: Array,
  },
  data() {
    return {
      selection: null,
      search: null,
      touched: false,
    };
  },
  computed: {
    validationRules() {
      return [
        ...(this.rules || []),
        (v) => !this.required || (v?.length ?? 0) > 0 || 'Value is required',
      ];
    },
  },
  methods: {
    onSearch(v) {
      if (!this.touched) return;
      this.search = v;
      const $self = this.$refs.combobox;
      $self.errorBucket = this.validationRules.filter(f => f(v) !== true);
      $self.valid = $self.errorBucket.length === 0;
      this.$emit('input', v);
    },
  },
  watch: {
    selection: {
      handler(v) {
        this.$emit('input', v);
      },
    },
    value: {
      immediate: true,
      handler(v) {
        if (this.search) { return; }
        this.selection = v;
      },
    },
  },
});

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Creating a dynamic collection of N triangles in a container using CSS

In my current project, I am developing an Electron+Vue application that features a grid-styled map. Each cell on the map represents a room, and I want to indicate walls within these cells. Specifically, for directions North, South, East, and West, I can us ...

Creating an image on an HTML canvas using RGB values

Looking for assistance on displaying an image using HTML Canvas with three 12x12 arrays containing R, G, and B values. I've seen Canvas demos showing how to draw lines, but nothing on using RGB arrays to create an image. Any tips or guidance would be ...

How do I utilize Ajax to compare the value selected from a drop down menu in a form with entries in my database, and retrieve the corresponding record/row to automatically fill in a form?

I have a drop-down menu where users can select an option. I need to match the selected value with the corresponding record in my database under the "invoiceid" column, and then populate a form with the associated data when a prefill button is clicked. Belo ...

Why does the address bar show value changes in IE when using window.location.hash, but the value doesn't change in the DOM when going

Here is a sample JavaScript code that attempts to detect the back button event: document.location.hash="#1"; document.location.hash="#2"; document.location.hash="#3"; function check() { if("#3"!=window.location.hash) { alert("Back button clic ...

Instructions for activating and deactivating a numerical input field with a checkbox

Is there a way to create a pair of a checkbox and number field that are linked together? When the checkbox is clicked, it should disable the associated number field. Javascript File: $(document).ready(function(){ $("input[name=check]").click(function(){ ...

Displaying the size of a JSON array in Vue.js

When working on my Vue.js project, I encountered an issue. I wanted to display the length of specific data from an API. However, when I used the code below, the status sold length appeared as 5 repeated five times instead of just once with a value of 5. ...

Scroll through the div to quickly find the relevant content

I have implemented the following HTML structure: <div style="height:200px;overflow-y:scroll;"> <table>.....</table> </div> By using this setup, I am aiming to replicate the functionality of an expanded <select> control wit ...

Searching for the precise draggable grid line position in rulerguides.js - tips and tricks!

Currently, I am utilizing rulerguides.js in my project. I have customized it for a specific div to display rulers and grid lines. You can refer to this FIDDLE. The rulers are functioning properly, but the draggable grid lines are being calculated based on ...

The Vuetifyjs 2.0 theme remains unchanged despite using watchers

When working with Vuetifyjs v1.5, I was able to easily change the theme dynamically using Vue watchers. However, this functionality seems to have changed with the update to Vuetifyjs 2.0. Current Versions: Vue - 2.6.10 Vuetify - 2.0 Vuex - 3.1.1 export ...

What causes the Object expected error in jQuery?

Looking for a way to demo horizontal collapse pane with a simple web page that includes html, css, and jquery. <html> <head> <script type="text/javascript" src="//code.jquery.com/jquery-1.10.1.js"></script> <title>Sa ...

Skipping MongoDB in loop operations in a Node.js environment.The original text was modified to

Apologies for the beginner question (The following code is related to express framework and mongoose DB) I am attempting to iterate through the array 'Users' which contains usernames. Then, I am trying to match them in the mongoose database to r ...

Text randomly appears on the html page

I've been dedicating a significant amount of time to finding a solution, but haven't had any luck. I'm aiming to create a visual effect where 10 words with varying font sizes slide in from different directions on a canvas within my document ...

Ways to move down only one level of an element's children, excluding sub-levels

When implementing this code snippet: jQuery: $(this).next().slideDown() with a selector :$(this).next() HTML: <li class="sub-menu two-level-collapse"> <a href="javascript:void(0);" class="two-level-collapse parent">< ...

What is the best way to assign a return value to a variable in JavaScript?

var robotDeparture = "The robot has set off to buy milk!" var farewellRobot = return robotDeparture; I'm attempting to show the content of the robotLeaves variable using a return statement. Furthermore, I intend to assign this return statement to a v ...

How can I use Angular to bind the text entered in an `input` within one `ng-repeat` `div` to another `div` within a different `ng-repeat`?

I am trying to create a dynamic Angular-based webpage where input tags are connected to h3 tags in separate DIVs. Below is the setup of my HTML page (as seen on Plunker): <!DOCTYPE html> <html> <head> <style type="text/css> ...

An error stating that "DataTable is not a recognized function" occurred within the document function

Previously, I set up datatables using the code below: $(function () { $('#keywords-table').DataTable({ "ajax": ({ url: "{{ route('getKeywordsByProductId') }}", method: "get", ...

How can Backbone.js utilize Ajax to bind data to a Collection?

I've recently delved into the world of Backbone.js. My goal is to create a Collection and populate it with data sourced externally. The current format of the data is CSV, not JSON. I am considering converting it to JSON for simplicity. Therefore, I ...

Emulate the CSS hover effect with jQuery 코드 희미한

Is there a method in jquery or any other technology that can detect event X and trigger a different event elsewhere? Currently, I am working with an image that has an image map. When a user hovers over a specific area on the map, I would like another part ...

I attempted to include multiple images in my HTML using Vue.js, but encountered an error message stating "illegal invocation"

Here is my HTML code: <form method="POST" v-on:submit.prevent="handleSubmit($event);"> <div class="row"> <div class="col-md-4"> <div class="form-group label-floating"> <label class="control-label">Name</label> <input ...

Tips for utilizing ajax function to refresh database entries

I am working with a customer information table that is populated from a database. The last column in this table contains an edit button which, when clicked, shows a popup window with text fields pre-filled with database values. I want users to be able to u ...