Use vee-validate to validate select list with radio button exchange not show up validate message

martin wang picture martin wang · Nov 25, 2017 · Viewed 11.5k times · Source

I have a form use radio to exchange select lists but the validate message seems not to work correctly. this is my form and the TypeA validate message does work: enter image description here

but when I change radio button to TypeB the validate message does not work: enter image description here

and also if I click submit button and if TypeA validate is not correct and I change to TypeB to submit it, the validation will not pass because it looks like vee-validate only validated TypeA...

And here is my code:

I don't know how to fix this problem, can someone help me?

Answer

Niklesh Raut picture Niklesh Raut · Nov 25, 2017

Use v-show instead v-if to watch changes, because v-if add/remove dom element and vee-validate checks in DOM.

<form id="form" @submit.prevent="validateBeforeSubmit">
    <label>Type A</label>
    <input v-on:change="changeType" type="radio" v-model="Type" value="TypeA" />
    <label>Type B</label>
    <input v-on:change="changeType" type="radio" v-model="Type" value="TypeB" />

    <table>
        <tr v-show="Type==='TypeA'">
            <td>
                <select v-model="TypeA" v-validate="'required|not_in:Choose'" name="TypeA">
                    <option v-for="option in TypeAOptions" v-bind:value="option.value">
                        {{ option.value }}
                    </option>
                </select>
                <span v-if="errors.has('TypeA')">
                    {{ errors.first('TypeA')}}
                </span>
            </td>
        </tr>
        <tr v-show="Type==='TypeB'">
            <td>
                <select v-model="TypeB" v-validate="'required|not_in:Choose'" name="TypeB">
                    <option v-for="option in TypeBOptions" v-bind:value="option.value">
                        {{ option.value }}
                    </option>
                </select>
                <span v-if="errors.has('TypeB')">
                    {{ errors.first('TypeB')}}
                </span>
            </td>
        </tr>
    </table>
    <button type="submit">Submit</button>
</form>

<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script src="https://cdn.jsdelivr.net/npm/vee-validate@latest/dist/vee-validate.js"></script>

<script>
    Vue.use(VeeValidate);
    var form = new Vue({
        el: '#form',
        data: {
            Type: 'TypeA',
            TypeA: 'Choose',
            TypeAOptions: [{
                    value: 'Choose'
                },
                {
                    value: 'A',
                },
                {
                    value: 'B'
                },
                {
                    value: 'C'
                },
                {
                    value: 'D'
                }
            ],

            TypeB: 'Choose',
            TypeBOptions: [{
                    value: 'Choose'
                },
                {
                    value: '1'
                },
                {
                    value: '2'
                },
                {
                    value: '3'
                },
                {
                    value: '4'
                }
            ],
        },
        computed:{
        },
        methods: {
            changeType:function(){
              this.errors.clear();
            },
            validateBeforeSubmit() {
                this.$validator.validate(this.Type).then((result) => {
                    if (result) {
                        alert("Submit Success");
                        return;
                    }
                    alert("Correct them errors!");
                });
            }
        }
    })
</script>

Also you are validating all fields means at the time both dropdown is validating.

To make it work. Means to validate only one dropdown at a time I changed this line. From

this.$validator.validateAll()

To

this.$validator.validate(this.Type)