6

I have a multi step form. Each step has its own validation and there is a "next" button for each step.

I'd like to check whether the form passes validation whenever the next button is clicked, and if validation fails, prevent moving to the next step.

Here is my form:

<form method="post">
  <div id="step1" v-show="step == 1">  
    <div class="form-group" :class="{'has-error': errors.has('startDate') }">
      <label for="startDate">Start Date</label>
      <input type="text" name="startDate" class="form-control" id="startDate" v-validate="'required'">
      <span v-show="errors.has('startDate')" class="text-danger">@{{ errors.first('startDate') }}</span>
    </div>
    <div class="form-group" :class="{'has-error': errors.has('adDuration') }">
      <label for="">Ad Duration</label>
      <select class="form-control" name="adDuration" v-on:change="total" v-model="adDetailOrder.unit" v-validate="'required'">
        <option v-for="adDuration in adDurations" :value="adDuration.unit">@{{ adDuration.text }}</option>
      </select>
      <span v-show="errors.has('adDuration')" class="text-danger">@{{ errors.first('adDuration') }}</span>
    </div>
  </div>

  <div id="step2" v-show="step == 2">
    //input form and v-validate goes here
  </div>

  <div id="step3" v-show="step == 3">
    //input form and v-validate goes here
  </div>
</form>

<button v-if="step == 1" type="button" class="btn btn-default" v-on:click="nextStep(2)">Next</button>
<button v-if="step == 2" type="button" class="btn btn-default" v-on:click="nextStep(3)">Next</button>
<button v-if="step == 3" type="button" class="btn btn-default" v-on:click="nextStep(4)">Next</button>

The next button runs this method:

nextStep: function(stepNumber) {
    //check validation step 1
    if (this.step == 1) {
        this.$validator.validate('startDate', this.startDate);
        this.$validator.validate('adDuration', this.adDuration);

        //if step 1 validation success
        //go to next step
        this.step = stepNumber;

        //else
        //stay this step and show error
    }
},

This code advances to the next step even when validation fails.

How can I make this work?

1
  • Have you figured out how to do it? Commented Sep 19, 2017 at 14:32

3 Answers 3

5

I don't believe you need to call validate explicitly. Errors will be detected automatically. In your nextStep method you could just check if there are any errors and return if there are.

nextStep: function(stepNumber) {
    if (this.errors.any())
        return

    ...
}

Additionally, how about disabling the button that calls nextStep if there are any errors?

<button :disabled="errors.any()" @click="nextStep">Next</button>
Sign up to request clarification or add additional context in comments.

2 Comments

your souliton only work for step 1 validation, the other step is not working, I just edited with my form structure, could you please check it?
@DarkCyber Why would it just work with step 1? Assuming you build out the forms and all of them use validation in the same scope (which it appears they do) errors.any() should return errors from every step. Perhaps you could build a working example in a fiddle.
1

Way too late to actually help Dark Cyber, but for anybody else looking here, $validator.validate returns a Promise, so you could do

Promise.all([this.$validator.validate('startDate'), this.$validator.validate('adDuration')])
  .then(validArray => {

    //validArray should be an array of booleans, make sure they're all true
    if (validArray.every(Boolean)) {
      this.step = stepNumber
    } else {
      // Otherwise go to the catch block
      throw new Error();
    }
  }).catch(error => {
    // error handling
  });

Comments

1

Use: errors.any() to check all

methods: {
  submit () {
    const isVaild = !this.errors.any()
  }
}

And you can also use $validator.validate('my_field') to check a single field

methods: {
  async submit () {
    const isVaild = await this.$validator.validate('email')
    // const isVaild = await this.$validator.validate('email') && await this.$validator.validate('confirm_email')
  }
}

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.