Vuelidate allows for validation to occur upon clicking a button, rather than waiting for the field

As I navigate my way through learning vuelidate, everything seems to be going smoothly, except for one thing. I can't figure out how to trigger validation only when the "Submit" button is clicked. Currently, the fields turn red as soon as I start typing, but I want them to wait until the user is ready to submit the form.

This is my progress so far:

Vue.use(window.vuelidate.default)
const { required, minLength, sameAs } = window.validators

new Vue({
el: "#app",
  data: {
  user: {
    login: '',
      password: '',
      repeatedPassword: ''
    }
  },
  validations: {
  user: {
    login: {
      required,
        minLength: minLength(5)
      },
      password: {
      required,
        minLength: minLength(8)
      },
      repeatedPassword: {
      required,
        sameAs: sameAs('password')
      }
    }
  }
})
input {
  border: 1px solid silver;
  border-radius: 4px;
  background: white;
  padding: 5px 10px;
}

.error {
  border-color: red;
  background: #FDD;
}

.error:focus {
  outline-color: #F99;
}

.valid {
  border-color: #5A5;
  background: #EFE;
}

.valid:focus {
  outline-color: #8E8;
}
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/vuelidate/dist/validators.min.js"></script>
<script src="https://unpkg.com/vuelidate/dist/vuelidate.min.js"></script>
`<div id="app">

  <input type="text" placeholder="login"
    v-model="user.login"
    v-on:input="$v.user.login.$touch"
    v-bind:class="{error: $v.user.login.$error, valid: $v.user.login.$dirty && !$v.user.login.$invalid}">
  <br/>    
  <input type="password" placeholder="password"
    v-model="user.password"
    v-on:input="$v.user.password.$touch"
    v-bind:class="{error: $v.user.password.$error, valid: $v.user.password.$dirty && !$v.user.password.$invalid}">
  <br/>  
  <input type="password" placeholder="repeat password"
    v-model="user.repeatedPassword"
    v-on:input="$v.user.repeatedPassword.$touch"
    v-bind:class="{error: $v.user.repeatedPassword.$error, valid: $v.user.repeatedPassword.$dirty && !$v.user.repeatedPassword.$invalid}"
  >
  <button :disabled="$v.user.$error" @click="$v.user.$touch()">
    Submit!
  </button>
</div>`

Answer №1

Adapting to the Vuelidate approach has been a bit challenging for me, but essentially, it operates in the following manner:

By setting it up this way, you can implement validation for individual form inputs/elements and then conduct an overall check to determine if the form is "dirty" and/or "invalid"

form: {
"name": {
"required": false,
"$invalid": true,
"$dirty": false,
"$error": false,
"$pending": false,
"$params": {
  "required": {
    "type": "required"
  }
}
},
"Age": {
  "required": false,
  "$invalid": true,
  "$dirty": false,
  "$error": false,
  "$pending": false,
  "$params": {
    "required": {
      "type": "required"
    }
  }
},
"$invalid": true, <------- This indicates whether the form is valid/invalid
"$dirty": false, <------- This reveals if the form has been interacted with.
"$error": false,  <-------  This assesses both invalidity and dirtiness
"$pending": false,
"$params": {
   "nestedA": null,
   "nestedB": null
}
}

In terms of practical application, one approach could involve triggering the validateform event upon submission.

@click.prevent="validateform"

Subsequently, create a validateform method within your Vue instance that verifies

$v.form.$invalid or $v.form.$error

and then either showcase errors or invoke the actual submit process.

Answer №2

After configuring the validations, all you need to do is invoke a method to validate any errors. Simply follow these steps:

<button @click="validate">Submit</button>

The validation method:

validate () {
  this.$v.$touch() // This will trigger validation for all fields
  if (!this.$v.$invalid) { // $invalid becomes true when validation fails
   // No validation errors found. Proceed with your desired action here
  }
}

Answer №3

Currently, the touched field turns red as soon as input is provided.

This indicates that the field is being marked as 'dirty' automatically, which was not the default behavior in the previous version (Vuelidate 2).

Please ensure that you do not have $autoDirty: true set or change it to "false."

In Vuelidate 2, all you need to do to achieve your desired outcome is to call $touch() on the submit click event, as $autoDirty defaults to false. Refer to Roland's answer for more details.

Answer №4

My approach to using VeeValidate 3 involves the following steps:

<validation-observer ref="jobValidation">
 <form>
     <button v-on:click="nextPage()" type="button">Next</button>
 </form>
</validation-observer>

Additionally, my implementation includes the following snippet within the methods:

nextPage(): void {                 
    const validation = (this.$refs.jobValidation as any);
    validation.validate().then(() => {
        if (validation.flags.invalid) {                           
            // Handling invalid inputs
            // Also displaying all errors in a summary
            validation.$children.forEach((child: any) => {
                child.errors.forEach((error: any) => {
                    console.log(error);
                });
                return;
            });
        } else {
            // Proceeding with valid data
            // Performing required actions
        }
    });  
},

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

Ensuring that at least one checkbox is selected with the help of vuejs

Ensuring that at least one checkbox is checked and the correct price is calculated is my priority. https://jsfiddle.net/snoke/1xrzy57u/1/ methods: { calc: function (item) { item.isChecked = !item.isChecked this.total = 0; for ...

Why is React's nested routing failing to render properly?

click here for image portrayal I am currently attempting to integrate react router, specifically a nested router. However, when I click the links on the contact page, no results are being displayed. Any assistance would be greatly appreciated. For more in ...

"Strategies for effectively utilizing the .find method to locate specific users within a database

I'm currently working on developing a User Authentication system, but I've hit a roadblock when it comes to verifying users. Specifically, I'm struggling with understanding how to iterate through all of my users in order to filter out their ...

Getting the JavaScript file name within another JavaScript file - a simple guide

Imagine having an HTML file that references two external JavaScript files. One of these JavaScript files contains errors (likely compilation errors), while the other file includes an onerror method without any issues. When you open the HTML file in a brows ...

Executing changes to Vuex store mutation for array manipulation

File Storage: state: { ... cases: [], ... mutations: { setCases(state, items) { // The 'items' variable contains only the first object in the array ... Component Implementation: // The 'resp' variable ...

Finding the source of the err.kind expression in the MERN stack: Unraveling the mystery

Recently, I've been delving into the world of MERN stack development and came across an interesting technique for Error Handling in a tutorial. The tutorial showcased various expressions that can be used to identify different types of errors being thr ...

Error: The hook call is invalid and can only be made within the body of a function component in ReactJS

Hello everyone, I am currently facing an issue with saving the lat and lng variables in the state within a hook. When trying to do so, I encounter the following error message: "Error: Invalid hook call. Hooks can only be called inside the body of a functio ...

In the production mode, Nuxt styles may not be properly applied

After working on this project for about four months, everything seems fine in the development version. However, once I build the project and upload it to the server, some of my styles are not applied. For more information, I have imported styles both in c ...

Having trouble retrieving a specific key from the state object in Redux using TypeScript

I have incorporated TypeScript into my Ionic project, using React hooks. I recently added an errorReducer to handle any errors that may arise from the server. Below is a snippet of my code: Action import { ERROR_OCCURRED } from "./types"; ...

The code coverage for the "rendering expectations" test in a particular component is insufficient

In order to test a specific component in my application, I am utilizing react-test-render. The test is intended to ensure that the component renders properly. Despite defining all the necessary properties for the component in the test file, the test cover ...

Tips for preventing the "Error: Avoided redundant navigation to current location: "/inside/home" when the authentication guard restricts access to the route

Upon logging out, I would like Vue to automatically navigate to the default landing page. The current behavior is causing Vue to redirect to the existing route instead. This redirection gets intercepted by a guard that prevents it and sends the user back ...

integrating material design components into Vue.js applications

My website is built on the Vue framework and webpack technology. I recently discovered Google's Material Components Web CSS framework, which can be easily implemented using a cdn or npm package for basic html/javascript websites. However, I am encoun ...

What is the best way to target the shadow DOM host element specifically when it is the last child in the selection?

I want to style the shadow DOM host element as the last child. In this particular situation, they are currently all green. I would like them to be all red, with the exception of the final one. class MyCustomElement extends HTMLElement { constructor() ...

Top method for utilizing overlays

Is there a method to randomly select hex codes for specific colors? I want to replicate the design in this image through coding. Image Here is the code I have so far: HTML <div id="group"> <div class="sub red panel"> </div><!--su ...

Is Fetch executed before or after setState is executed?

I've encountered an issue while trying to send data from the frontend (using React) to the backend (Express) via an HTML form, and subsequently clearing the fields after submission. The code snippet below illustrates what I'm facing. In this scen ...

Codeigniter session unexpectedly ends after AJAX call completes successfully

Currently, I am utilizing the CodeIgniter framework on a Heroku server with an AWS database. In my AJAX success function, I have a window.location.reload(); call which ends up destroying the session and redirecting to the login page. Is there a way to prev ...

"Send the selected radio button options chosen by the user, with the values specified in a JSON format

My current task involves inserting radio button values into a MySql database using Angular. The form consists of radio buttons with predefined values stored in a json file. Below is an example of how the json file is structured: //data.json [{ "surve ...

Tips for modifying the content displayed on a v-list in Vue.js dynamically

I am looking to create a dynamic list that displays data based on the selected key. The list will contain multiple items with different keys, and I want the flexibility to choose which data to display without hardcoding the actual key value. <template&g ...

Error in Mongoose validation: "Please provide a value for the 'first' field and the 'last' field."

Another user has previously posted a similar question, but I'm still struggling with my MongoDB website. I am working on a project to store names using mongoose. Here is the code for my routes and models: const router = require("express").Router(); c ...

Unable to retrieve the field value from the Json Object

I have a JSON object that I need to parse and display in a data table, but I'm having trouble reading the contents of the object. Here is my JavaScript function: finalGrid: function(data){ console.log("Final Grid"); var strJson = JSON.strin ...