Ensuring validity with Vuelidate for customizable fields

There's a form where fields are dynamically added on a click event. I want a validation error to appear when the field value is less than 9 digits after changing or blurring it. The issue is that since the fields are created dynamically with the same v-model, the rule applies to all of them. How can I make it so that it only affects the one the user is currently interacting with? Initially, the screen loads with 10 fields, and more can be added later. While filling out the first 10 fields, I don't want a validation message to pop up after the 5th one fails, affecting all subsequent fields.

Below is a simplified version of the code:

<template>
    <div>
        <div>
            <button @click="onAddBarcodes">Add More</button>
        </div>
        <div v-for="(barcode, index) in barcodes" :key="index">
            <div>
                <div>
                    <label>Starting Roll #:</label>
                    <input
                        name="startbarcoderoll"
                        maxlength="9"
                        v-model.trim="$v.barcode.barcodeStart.$model"
                        :id="barcode.id"
                        ref="bcentry"
                    />
                    <!-- max length message -->
                    <div v-if="!$v.barcode.barcodeStart.minLength">
                        <span
                            v-if="!$v.barcode.barcodeStart.minLength"
                        >App Barcode must be exactly {{$v.barcode.barcodeStart.$params.minLength.min}} characters.</span>
                    </div>
                </div>
                <button @click="onDeleteBarcodes(barcode.id)">Remove</button>
            </div>
        </div>
    </div>
</template>

<script>
const { minLength } = require("vuelidate/lib/validators");

export default {
    data() {
        return {
            barcodes: [],
            barcode: {
                barcodeStart: ""
            }
        };
    },
    validations: {
        barcode: {
            barcodeStart: {
                minLength: minLength(9)
            }
        }
    },
    methods: {
        scanBarcodeNumber(value) {
            this.barcode.barcodeStart = value;
            this.$v.barcode.barcodeStart.$touch();
        },

        onAddBarcodes() {
            const newBarcode = {
                id: Math.random() * Math.random() * 1000,
                barcodeStart: ""
            };
            this.barcodes.push(newBarcode);
        },
        onDeleteBarcodes(id) {
            this.barcodes = this.barcodes.filter(barcode => barcode.id !== id);
        }
    }
};
</script>

Here's a visual illustration of the problem:

Note: Vuelidate is installed globally within Vue for use across multiple components, which explains why it's not directly featured in this specific code snippet.

https://i.stack.imgur.com/ROZjE.png https://i.stack.imgur.com/xdOPD.png

Answer №1

Implement dynamic validations by using the validations function and adding a unique validation for each individual barcode.

Replace $v.barcode with $v[`barcode-${index}`] for each field:

<template>
    <div>
        <div>
            <button @click="onAddBarcodes">Add More</button>
        </div>
        <div v-for="(barcode, index) in barcodes" :key="index">
            <div>
                <div>
                    <label>Starting Roll #:</label>
                    <input
                        name="startbarcoderoll"
                        maxlength="9"
                        v-model.trim="$v[`barcode-${index}`].barcodeStart.$model"
                        :id="barcode.id"
                        ref="bcentry"
                    />
                    <!-- max length message -->
                    <div v-if="!$v[`barcode-${index}`].barcodeStart.minLength">
                        <span
                            v-if="!$v[`barcode-${index}`].barcodeStart.minLength"
                        >App Barcode must be exactly {{$v[`barcode-${index}`].barcodeStart.$params.minLength.min}} characters.</span>
                    </div>
                </div>
                <button @click="onDeleteBarcodes(barcode.id)">Remove</button>
            </div>
        </div>
    </div>
</template>

In your javascript section, define the validations function with the specified barcode validation for each field:

export default {
  validations() {
    const rules = {};
    this.barcodes.forEach((item, index) => {
      rules[`barcode-${index}`] = {
        barcodeStart: {
          minLength: minLength(9),
        },
      };
    });
    return rules;
  },
};

This approach may not be the most efficient, but it should accomplish what you desire.

Answer №2

If you're looking to enhance your form validation, consider implementing Vuelidate's $each feature.

To learn more, check out the documentation provided here:

For further insights, feel free to explore this informative article on the topic:

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

Vue state loses data upon page refresh causing fetched content to vanish

Fetching data from an API and updating the store fetchVisits({commit}) { axios.get('/api/visits') .then(res => { commit('FETCH_VISITS', res.data) }).catch(err => { ...

Insert a record at the start of a data grid - JavaScript - jQuery

What is the most effective way to use jQuery for adding a new row at the top of a table? Here is an example table structure: <table id="mytable" cellpadding="0" cellspacing="0"> <tr> <td>col1</td> ...

Issues with AngularJS dirty validation for radio buttons not being resolved

I have encountered an issue with my form fields. The validation for the email field is working correctly, but the radio button field is not displaying any errors when it should. I am using angular-1.0.8.min.js and I cannot figure out why this is happenin ...

Angular JS displays an error message when the user selects an input field and fails to provide any input

On my wizard steps application, I have implemented Angular JS validation that displays errors when the user enters and removes a character in the input field. However, I am trying to figure out how to show the error message if the user tabs onto the fiel ...

What is the best way to navigate from a button in NextJS to another page that I have built within the same application?

As I work on developing a website for a pet rescue charity using Next.js, I am facing an issue with getting my button or link to function correctly. Every time I try to navigate to another page within my Next.js app, I encounter a 404 error stating "This p ...

Jest Test - Uncaught TypeError: Unable to create range using document.createRange

my unique test import VueI18n from 'vue-i18n' import Vuex from "vuex" import iView from 'view-design' import {mount,createLocalVue} from '@vue/test-utils' // @ts-ignore import FormAccountName from '@/views/forms/FormAcco ...

Ways to extract information from a text

I have a massive string, divided into two parts that follow this pattern: {\"Query\":\"blabla"\",\"Subject\":\"gagaga"}", {\"Query\":\"lalala"\",\"Subject\":\"rarara&bso ...

Implementing a Searchable Autocomplete Feature within a Popover Component

Having an issue saving the search query state. https://i.stack.imgur.com/HPfhD.png https://i.stack.imgur.com/HbdYo.png The problem arises when the popover is focused, the searchString starts with undefined (shown as the second undefined value in the ima ...

Define the input field as a specific type and disable the Material-UI text formatting

I am using a Texfield component from Material UI, but I have noticed that every time I type, the input stops and doesn't continue to the next letter. I have to click on it again in order to continue typing. When I remove the onChange method, the data ...

Is it possible to transfer data from javascript to php through ajax?

I am attempting to extract the data speedMbps from my JavaScript code using Ajax to send the data to my PHP script, but unfortunately, I am not receiving any output. My experience with Ajax is limited to implementing auto-completion feature. <script sr ...

Scrolling the Ionic framework to a position below zero

My ion scroll is synchronized with another component for scrolling. I achieve this by using the function scroll1.scrollTo(left, top, false); Unfortunately, this function does not allow scrolling to a negative position, such as scroll1.scrollTo(left, -50, ...

techniques for utilizing dynamic variables with the limitTo filter in AngularJS

<div class="container"> <div class="row" ng-repeat="cmts in courCmt.argument" ng-init="getUserInfo(cmts)"> <div class="col-sm-1 col-xs-2"> <div class="thumbnail"> &l ...

What could be causing appendChild to malfunction?

I'm having an issue trying to create three elements (parent and one child) where the third element, an <a> tag, is not appending to modalChild even though it's being created correctly. modal = document.createElem ...

Docker facing CORS problem when port is concealed

I'm currently working on establishing a connection between a Vue frontend app and a Lumen backend API. My goal is to achieve this without exposing the backend API port externally, keeping everything handled internally. The main reason behind this appr ...

Utilize underscore's groupBy function to categorize and organize server data

I am currently utilizing Angular.js in conjunction with Underscore.js This is how my controller is structured: var facultyControllers = angular.module('facultyControllers', []); facultyControllers.controller('FacultyListCtrl', [' ...

The Joi validate() function will return a Promise instead of a value when used within an asynchronous function

Trying to understand how async functions and the Joi.validate() function behave. Below is a function used for validating user input. const Joi = require("joi"); const inputJoiSchema= Joi.object().keys({ name: Joi.string(), email: Joi.string().require ...

Having issues with utilizing $fetchState in Nuxt 2.12

Recently, I've been exploring the new functionality outlined in the documentation. However, I'm encountering an error that states : Property or method "$fetchState" is not defined on the instance but referenced during render. Despite clearly ...

What is the best way to navigate to the bottom of a page when new data is added?

I've created a chat feature in my Ionic app, but the issue is that when a user receives a new message while being on the chat screen, the view doesn't automatically scroll down to show the new message. The user has to manually scroll down to see ...

Guide on transferring numerous files (50k+) from a folder to AWS S3 using node.js

Currently, my Node.js API on a Windows machine is generating numerous XML files that are later sent to an S3 bucket. The quantity of files sometimes surpasses 50k. For the uploading process, I am utilizing the aws-sdk package. Essentially, I iterate throu ...

Variability in the values returned by the useState hook

Currently, I am working on developing my initial user signup form, and I have encountered a challenge that seems relatively simple to resolve but goes beyond my current expertise. The issue pertains to the helperText for an MUI select component which is no ...