0

I am trying to understand and work around to validate a simple form but the problem I am facing is, when the page loads, it shows the "Error" or "Success" message, which should display only either on keypress or mouseout event.

Moreover, I cannot figure out how to validate the dropdown and finally when a user click submit, it can check all fields are filled and correct to submit the form. Following is my code and my link to JSFiddle

HTML

<div id="app">
  <div>
    <label for="name">Name</label>
    <input type="text" @keypress="checkField" v-model="name">
    <span v-if="checkName">Checks out </span>
    <span v-if="!checkName">Pleas enter valid name</span>
  </div>

  <div>
    <label for="Age">Age</label>
    <input type="number" @keypress="checkField2" v-model="age">
    <span v-if="checkAge">Enter Valid Age </span>
    <span v-if="!checkAge">Not a valid age</span>
  </div>

<div>
  <select name="" id="">
    <option disabled selected>Please Choose</option>
    <option v-for="gender in genders" :value="gender">
      {{gender}}
    </option>
  </select>
  <span v-if="genderField">Please select a gender</span>
  <span v-if="!genderField">Green means go</span>
</div>
 <div>
   <button @click="checkSubmit(e)">Submit</button>
 </div>
</div>

JS

 data: {
    name: "",
    checkName: "",
    age: "",
    checkAge: "",
    genders : ["Male",'Female',"Other"],
    genderField: "" 
  },
  methods: {
    checkField() {
      if (!this.amount) {
        this.checkName = true
      }
    },
    checkGender() {
                if(!this.genders){
            this.genderField = true
        }
    },
    checkSubmit(e){
        //check if all fields are filled before submitting
      alert("it is working")
      e.preventDefault()
    }
  }

})

2 Answers 2

1

There is a lot of ways to validate forms. I have a few tips for this kind of case.

  1. Use a form element with @submit.prevent="..." event handler. It will ensure a better user experience;

  2. Do not use @key* event handlers to validate or format a value, instead, use @input. It will prevent you from a lot of headache;

  3. Vue provide a API to watch all the attribute changes, not only when the user changes it.

For solve your problem, you can create a validation attribute and set its content acording the other attributes change.

See the example below:

BTW: I recommend that you take a look on vuelidate

const app = new Vue({
  data() {
    return {
      name: null,
      age: null,
      gender: null,
      genders: ['Male', 'Female', "Other"],
      validations: {}
    }
  },
  methods: {
    submit(e) {
      const keys = Object.keys(this.validations);

      // required fields
      const required = ['name', 'age', 'gender'];
      for (const key in required) {
        if (!keys.includes(required[key])) {
          alert('Please, insert a ' + required[key]);
          return;
        }
      }

      for (const key in this.validations) {
        if (!this.validations[key]) {
          alert('Please, insert valid ' + key);
          return;
        }
      }
      alert("ok");
    }
  },
  watch: {
    name(newValue) {
      this.validations.name = newValue > '';
    },
    age(newValue) {
      this.validations.age = newValue > 0;
    },
    gender(newValue) {
      this.validations.gender = this.genders.includes(newValue);
    }
  }
});

app.$mount("#app");
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <form @submit.prevent="submit">
    <div>
      <label for="name">Name</label>
      <input type="text" v-model="name">
      <span v-if="'name' in validations && validations.name">Checks out </span>
      <span v-if="'name' in validations && !validations.name">Pleas enter valid name</span>
    </div>

    <div>
      <label for="age">Age</label>
      <input type="number" v-model="age">
      <span v-if="'age' in validations && !validations.age">Enter Valid Age</span>
    </div>

    <div>
      <label for="gender">Gender</label>
      <select name="gender" v-model="gender">
    <option disabled selected>Please Choose</option>
    <option v-for="gender in genders" :value="gender">
      {{gender}}
    </option>
  </select>
      <span v-if="'gender' in validations && validations.gender">Green means go</span>
      <span v-if="'gender' in validations && !validations.gender">Please select a gender</span>
    </div>

    <input type="submit" value="Submit">
  </form>
</div>

Sign up to request clarification or add additional context in comments.

5 Comments

Vuelidation is nice.thank you, how does validations get populated? it is not connected to any model. I never used watch, where is watch methods get executed? and when you do age' in validations && !validations.age what does first part do? and when u say use @submit what is the difference between using it or @click I am not a pro in JS (sorry)
validations is populed in watch methods. watch methods are executed when the attributes changes (reference), in this case, when user inputs some value. 'age' in validations checks if the watcher was executed and validation.age has some value. I think @submit is better than @click because user can submit a form pressing the enter key too, not just clicking on the button. If your question was answered, please, flag it.
Still confused about how 'age' in validations works.
'age' in validations is a flag that means: "has the validation been done?". The initial value of validations is an empty object, so 'age' in validations returns false. When age attribute changes the watcher is executed validating its value and setting validations.age. After that, 'age' in validations returns true regardless validations.age being true or false.
In another words: 'age' in validationsmeans: "Has the user input some value on age field?"
0

In Angular, we have a built-in option to validate forms. But Vue offers very limited functionality when it comes to create and validate forms. To add more functionality, we have to install a separate package called Vuelidate to validate our Vue application forms.

What is Vuelidate?
According to the Vuelidate website:
“Vuelidate 2 is a simple, but powerful, lightweight model-based validation for Vue.js 3 and Vue 2.x.”

Install

npm install @vuelidate/core @vuelidate/validators

Reference:
https://aaqibqs.medium.com/learn-form-validation-in-vue-3-in-10-minutes-with-vuelidate-8929c5059e66

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.