Tips for effectively utilizing Vuelidate to display errors selectively after the user has completed input:

I have implemented a form using Bootstrap-Vue with some Vuelidation code applied to it.

<b-form @submit.prevent="onSubmit">
      <input type="hidden" name="_token" :value="csrf" />
      <transition-group name="fade">
        <b-form-select
          :class="{ 'hasError': $v.form.dobDate.$error }"
          class="mb-3"
          name="dobDate"
          id="dobDate"
          v-model.lazy="$v.form.dobDate.$model"
          :options="optionsDays"
          v-if="isSixteen"
          key="dobDateSelect"
        >
          <template slot="first">
            <option value disabled>Please select a date</option>
          </template>
        </b-form-select>
      </transition-group>
      <transition-group name="fade">
        <b-form-select
          :class="{ 'hasError': $v.form.dobMonth.$error }"
          class="mb-3"
          name="dobMonth"
          id="dobMonth"
          v-model.lazy="$v.form.dobMonth.$model"
          :options="optionsMonths"
          v-if="isSixteen"
          value="optionsMonths.key"
          key="dobMonthSelect"
        >
          <template slot="first">
            <option value disabled>Please select a Month</option>
          </template>
        </b-form-select>
      </transition-group>

      <b-alert
        show
        variant="danger"
        class="error"
        v-if="!$v.form.dobYear.required"
      >This field is required</b-alert>

      <b-alert
        show
        variant="danger"
        class="error"
        v-if="!$v.form.dobYear.minLength"
      >Field must have at least {{ $v.form.dobYear.$params.minLength.min }} characters.</b-alert>

      <b-alert class="error" v-if="!$v.form.dobYear.numeric">Please enter a valid year of birth</b-alert>

      <b-alert show variant="danger" v-if="belowSixteen">You are underage</b-alert>

      <b-form-input
        :class="{ 'hasError': $v.form.dobYear.$error }"
        placeholder="Year of Birth"
        v-model="form.dobYear"
        @blur="$v.form.dobYear.$touch()"
        autofocus
        class="form-control mb-3"
        name="year"
        id="year"
        maxlength="4"
        @keyup="checkAge"
      ></b-form-input>

      <b-button
        class="btn btn-lg btn-primary btn-block"
        type="submit"
        variant="primary"
        :disabled="$v.$invalid||belowSixteen"
      >Submit</b-button>
      <b-alert
        show
        variant="danger"
        v-if="belowSixteen"
        class="error mt-3"
      >Sorry you have to be over 16 to play</b-alert>
    </b-form>

However, I am facing an issue where errors are displayed immediately when the page loads, which can be disruptive for users. I want the errors to appear only after the user has interacted with the input/select element.

I attempted to use @blur="$v.form.dobYear.$touch()" but it doesn't seem to be working properly. What could be causing this problem?

Here is a snippet of how my validation rules are defined in the script:

validations: {
    form: {
      dobYear: {
        required,
        minLength: minLength(4),
        maxLength: maxLength(4),
        numeric
      },
      dobMonth: {
        required: requiredIf(function() {
          return this.isSixteen;
        })
      },
      dobDate: {
        required: requiredIf(function() {
          return this.isSixteen;
        })
      }
    }
  }

Answer №1

Implementing $touch() during the blur event is considered correct. However, you may want to consider a slightly different approach using the state attribute provided by bootstrap-vue. For more detailed information, you can refer to this link: Form input [contextual states]

For example:

<b-form-input
  v-model="form.name"
  type="text"
  @blur="$v.form.name.$touch()"
  :state="$v.form.name.$dirty ? !$v.form.name.$anyError : null"
/>
<b-form-invalid-feedback :state="$v.form.name.$dirty ? !$v.form.name.$anyError : null" >
  Some kind of invalid feedback Message here
</b-form-invalid-feedback>


Furthermore, I am curious as to why you are using v-model with a validation model as shown below.

v-model.lazy="$v.form.dobMonth.$model"

Wouldn't it be sufficient to use v-model within data() like demonstrated below?

v-model.lazy="form.dobMonth"

Answer №2

You can structure it in the following way:

<div v-if="$v.email.$dirty"> 
<b-alert
    show
    variant="danger"
    class="error"
    v-if="!$v.form.dobYear.required"
>This field is mandatory</b-alert>

<b-alert
    show
    variant="danger"
    class="error"
    v-if="!$v.form.dobYear.minLength"
>Field should contain at least {{ $v.form.dobYear.$params.minLength.min }} characters.</b-alert>

<b-alert class="error" v-if="!$v.form.dobYear.numeric">Please input a valid year of birth</b-alert>

<b-alert show variant="danger" v-if="belowSixteen">You are under the age limit</b-alert></div>

Learn more

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

Tips for refreshing the tawk.to widget when the language changes with the help of i18next

Utilizing i18n-jquery for language switching and integrating the tawk.to chat widget, I've successfully loaded different languages on page reload. However, due to i18n not refreshing the page (which I don't want to do), I need to figure out how t ...

Problem encountered when attempting to add elements to an array within a nested

When running this code, everything works correctly except for the array pushing. After checking the console.log(notificationdata), I noticed that notification data gets its values updated correctly. However, when I check console.log(notifications), I see ...

Difficulty occurred when trying to import Polymer components

Currently, I am in the process of learning how to utilize Polymer. I meticulously followed the instructions provided exactly as specified here. However, upon reaching step 3 and adding the import for paper-checkbox, an error presented itself: Error: A c ...

Is there a way to align these side by side?

Is it a silly question? Perhaps. But I can't seem to figure out how to align my text and colorpicker on the same line instead of two. Take a look at my fiddle. I've tried removing display:block and clear:both, but that didn't do the trick. H ...

Make sure the "Treat labels as text" option is set to true when creating a chart in a Google spreadsheet using a script

I am currently working on a script using Google Spreadsheet Apps Script interface and I need to set the marker for 'Treat labels as text' to true. Despite searching through App Script documentation, I couldn't find any specific mention of t ...

Challenges with the Sumo Select Refresh Feature

I am having trouble with Sumo select not refreshing the data properly. The action method is returning the correct list, but it seems like the JQUERY multi-select rebuild() function is missing. Is there something I'm overlooking? $("#ddlCountry&q ...

Looking for a way to add interactivity to this canvas rectangle?

ctx.fillStyle = "#9b958c"; ctx.fillRect(sampleRectX, sampleRectY, sampleRectW, sampleRectH); ctx.fillStyle = "#fff"; ctx.fillText("Click here to play again.", sampleTextX, sampleTextY); This clickable rectangle has been giving me some trouble. While I fou ...

Why is the parameter declared if its value is never even used? Seems redundant

When trying to send an email, I've encountered an issue with my controller method: const send = function (subject, template, to, options) { // While VSC points out that "subject" is declared but its value is never read, // it does not signal ...

Eslint is unable to resolve issues within vue.js code

My first step was creating a vue project. npm init vue@latest Here are the settings I used. Next, I added rules to the .eslintrc.cjs file. /* eslint-env node */ require('@rushstack/eslint-patch/modern-module-resolution') module.exports = { r ...

One-of-a-kind browser identification for users, no login required

I have an online boutique and I want to enable customers to make purchases without creating an account. To achieve this, I need a way to associate a selected list of items with a user. Initially, I considered using the IP address for this purpose but fou ...

Switching on the click functionality

I was able to successfully toggle a boolean variable along with some other options. However, I encountered an issue when trying to create another click function for a different button to set the boolean variable to false. Here is my code: let manageme ...

What could be causing the error 'i is not defined' in my Vue.js component script when using a basic for loop?

I have a task where I need to sort an array by version and then move all elements starting with 'ipad' to the end of the list. This code snippet is extracted from a single file Vue.js component: computed: { orderedUsers: function () { ...

Are there any methods to determine the way in which a user has absorbed the content of a post

This particular question sets itself apart from the one found here, as it aims to detect various user behaviors beyond just browser activity. Specifically, I am interested in identifying behaviors such as: Rapidly skimming through an article from start ...

Pattern for validating mobile numbers with extensions using regular expressions

I am struggling to combine multiple separate regex validations into one for my mobile number validation requirements. The criteria include validating mobile numbers with a country code or starting with 00, as well as checking if they contain an extension n ...

What is the best way to attach a tag or label onto multiple objects so that it remains facing the camera whenever the user interacts with the objects?

My goal is to create a tag or label that always faces the camera when a user clicks on an object, even if that object is rotated. How can I achieve this? I've been advised to use an Orthogonal camera, but I'm not sure how to do that. Additionall ...

JavaScript completely transforms the HTML code for each element in an array

I'm having trouble adjusting the inner HTML of specific "div" elements using JavaScript. When I try to change the HTML of a single element in an array, it ends up changing all elements instead. let div_length = 2; const divs = new Array(div_length).f ...

Guide on extracting nested JSON data values using JavaScript

{ "_id" : ObjectId("587f5455da1da85d2bd01fc5"), "totalTime" : 0, "lastUpdatedBy" : ObjectId("57906bf8f4add282195d0a88"), "createdBy" : ObjectId("57906bf8f4add282195d0a88"), "workSpaceId" : ObjectId("57906c24f4add282195d0a8a"), "loca ...

Having issues with IE8 and SmoothGallery script errors

I'm currently utilizing the SmoothGallery plugin created by Jon Designs to enhance the website of one of my clients. However, there seems to be a minor issue in Internet Explorer 8 when attempting to navigate to the next image. Interestingly enough, a ...

Angular loop is unable to detect changes in the updated list

My Angular application is facing a peculiar issue that I can't seem to figure out. // Here are the class attributes causing trouble tenants: any[] = []; @Input() onTenantListChange: EventEmitter<Tenant[]>; ngOnInit(): void { this. ...

Executing a pair of queries within the same table and integrating them within a unified route

How can I efficiently execute two queries on the same table in my project? I have been considering using promises, but my knowledge on them is limited. Even though I've researched about it, I am struggling to implement the correct structure. My main ...