Shaik Salima
Shaik Salima

Reputation: 19

How to change input filed border color into red. When fields are empty

Here I have written a code for validating form input fields in Vue. And it is working fine when input fields are empty the form is not navigating to the next step. My issue is that while the field is empty, and the user tries to navigate to the next step, the input field border color should change in red. If one field is empty and the user is trying to navigate another step, the navigation should prevent, and the empty fields' border should be displayed in red.

<div id="vk_app">
  <form>
  
  <div v-if="step === 1">

    <h1>Step One</h1>
    <p>
    <legend for="name">Your Name:</legend>
    <input id="name" name="name" v-model="name">
    <input id="name" name="name" v-model="age">
    </p>

    <button @click.prevent="next()">Next</button>

  </div>
  <div v-if="step === 2">
      <template>
       <input id="name" name="name" v-model="address">
        <input id="name" name="name" v-model="h_no">
        <input id="name" name="name" v-model="mobile">
        <button @click.prevent="prev()">Previous</button>
        <button @click.prevent="next()">Next</button>
      </template>
  </div>

  <div v-if="step === 3">
    <template>
       <input id="name" name="name" v-model="subject">
        <input id="name" name="name" v-model="occupation">
        <button @click.prevent="prev()">Previous</button>
        <button @click.prevent="next()">Next</button>
      </template>

    <button @click.prevent="prev()">Previous</button>
    <button @click.prevent="submit()">Save</button>

  </div>
  </form>
</div>

vue.js

const app = new Vue({
  el:'#vk_app',
  data() {
    return {
      step:1,
        name:null,
        age:null,
        city:null,
        state:null,
    }
  },
  methods:{
    prev() {
      if(this.checkForm()) {
        this.step--;
      }
    },
    next() {
      if(this.checkForm()) {
        this.step++;
      }
    },
    checkForm: function (e) {
      if (this.name && this.age) {
        return true;
      }

      this.errors = [];

      if (!this.name) {
        this.errors.push('Name required.');
      }
      if (!this.age) {
        this.errors.push('Age required.');
      }

      e.preventDefault();
    }
    }
});

Upvotes: 0

Views: 5385

Answers (3)

Ian Cho
Ian Cho

Reputation: 107

We have a blur event. When blur event fired, if the input box was empty (or whatever you want), add a class such as "red" to the input box.

<input id="name" name="name" v-model="name" @blur="validation($event.target)">

const validation = el => {
    if (!el.value) {
        // this is a very simple examples. I don't recommend using jQuery.
        $(el).addClass('red'); 
    }
};

Add.

You can use the method on Next() method.

<input id="name" name="name" v-model="name" ref="name">
const next = () => {
    const inputName = this.$refs.name; // this if for just Vue2.
    if (!inputName.value) {
        $(inputName).addClass('red');
    }
};

Upvotes: 0

Riyaz Khan
Riyaz Khan

Reputation: 3238

Here is my answer for your code example, it will work when you click on next button.

Updated HTML and Inputs:

<div id="vk_app">
    <form>
      <div v-if="step === 1">
        <h1>Step One</h1>
        <legend for="name">Your Name:</legend>
        <input id="name" :class="errorField.name ? 'error-input' : ''" name="name" v-model="name" />
        <input id="name" :class="errorField.age ? 'error-input' : ''" name="name" v-model="age" />
        <button @click.prevent="next()">Next</button>
      </div>
      <div v-if="step === 2">
          <template>
          <input id="name" name="name" :class="errorField.address ? 'error-input' : ''" v-model="address" />
            <input id="name" name="name" :class="errorField.h_no ? 'error-input' : ''" v-model="h_no" />
            <input id="name" name="name" :class="errorField.mobile ? 'error-input' : ''" v-model="mobile" />
            <button @click.prevent="prev()">Previous</button>
            <button @click.prevent="next()">Next</button>
          </template>
      </div>
      <div v-if="step === 3">
        <template>
          <input id="name" name="name" v-model="subject">
            <input id="name" name="name" v-model="occupation">
            <button @click.prevent="prev()">Previous</button>
            <button @click.prevent="next()">Next</button>
          </template>
        <button @click.prevent="prev()">Previous</button>
        <button @click.prevent="submit()">Save</button>
      </div>
    </form>
  </div>

Vue Functions and Data Update:

data() {
      return {
        errorField: { name: false, age: false, city: false, state: false },
        step:1,
          name:null,
          age:null,
          city:null,
          state:null,
      }
    },
    methods:{
      prev() {
        if(this.checkForm()) {
          this.step--;
        }
      },
      next() {
        if(this.checkForm()) {
          this.step++;
        }
      },
      checkForm: function (e) {
        if (this.name && this.age) {
          return true;
        }

        this.errors = [];

        if (!this.name) {
          this.errorField.name = true
          this.errors.push('Name required.');
        }
        if (!this.age) {
          this.errorField.age = true
          this.errors.push('Age required.');
        }
      }
    }

Upvotes: 1

sree_pk
sree_pk

Reputation: 86

Since this feature(red border on invalid input) is required more often, we can use dynamic classes :

in style section define a class

.input--error{
    border-color:red;
}

and in template section add

:class="{'input--error':!name}"

to input tag making it look like :

 <input id="name" name="name"  v-model="name" :class="{'input--error':!name}"/>

The whole code would look something like this:

<template>
    <div>
        <!-- Using dynamic classes -->
        <input id="name" name="name"  v-model="name" :class="{'input--error':!name}"/>
        <input id="name" name="name" v-model="age" :class="{'input--error':!age}"/>
    </div>
</template>
<script>
export default {
    data(){
        return{
            name:null,
            age:null
        }
    }
}
</script>
<style scoped>
.input--error{
    border-color:red;
}
</style>


We could also add this directly in style attribute in input tag:

<input id="name" name="name" v-model="mobile" :style="!mobile ? 'border-color:red':''">

This would overcrowd the code unnecessarily.

Upvotes: 0

Related Questions