Vue

Vuelidate – How to …?

By December 9, 2018 May 8th, 2020 No Comments

How to validate checkbox (or perhaps even a radio button?)

1
        sameAs: sameAs( () => true )

Otherwise, the error is thrown first but if you check and uncheck again and submit the form again then the error won’t be thrown.

Source: https://github.com/vuelidate/vuelidate/issues/332

$v.days.$dirty && !$v.days.required $v.loan_purpose.$error $v.call_email_address.$invalid

How to use requiredIf?

1
2
3
4
5
6
7
8
9
kindOfVehicle: {
            required: requiredIf(function (nestedModel) {
                return this.currentStep === 1;
            })
        },

name: {
    required: requiredIf('document')
},

How to check for a field with vuelidate whether it is valid or invalid inside the vue instance?

1
this.$v.call_email_address.$invalid

Form dirty touch and validity check


1
2
3
4
var self = this;
self.$v.$touch();
if (!self.$v.$invalid) {
}

Bootstrap 4 input field validation example


1
2
3
4
5
6
7
8
9
10
11
<div class="slide-ranger col-md-12">
    <label for="amount" class="control-label sr-only">Loan Amount</label>

    <input type="text" id="range" name="range" class="form-control" v-model="range" :class="{'is-invalid': $v.range.$error, 'is-valid': (!$v.range.$error && $v.range.$dirty)}" @keyUp="$v.range.$touch();">
    <div class="invalid-feedback" :class="($v.range.$error && $v.range.$dirty)">Please enter a valid loan amount
    </div>

                            <p id="slider-range-min"></p>
                            <span style="display: flex;justify-content: center;font-size: 10px;">* use the slider to select the desired loan amount or input manually</span>

                        </div>

Bootstrap 4 select / dropdown validation


1
2
3
4
5
6
7
8
9
10
<div class="form-group col-md-6 mt30">
                            <label class="control-label" for="loan_purpose">What is the purpose of loan?</label>
                            <select id="loan_purpose" name="loan_purpose" class="form-control" v-model="loan_purpose" :class="{'is-invalid': $v.loan_purpose.$error, 'is-valid': (!$v.loan_purpose.$error && $v.loan_purpose.$dirty)}"
                                @change="$v.loan_purpose.$touch();">
                                <option value="">Select purpose of loan</option>
                                <option value="Home Improvement/Renovation">Home Improvement/Renovation</option>
                                <option value="Bill Consolidation">Bill Consolidation</option>
                                <option value="Retail/Purchase">Retail/Purchase</option>
                            </select>
                        </div>

Vuelidate Nested Validation

The validation for nested validation is slightly tricky. It involves the use of $each and the methods in the computed no longer work for us. Shortly we will discuss why. Another thing is writing the errors for the HTML part also gets trickier with the loop.

Despite all these problems, the right understanding will help us set things up pretty quickly.

First thing first!

You should know about $v.

In the Vue debugging panel, you can view elements inside $v and this will help you see the things under the hood and whats going on?

Setting up the rules in the validations block should be identical to what you have in the data block. Just when you start the array or the object part with the brace inside the array. Have an $each over there.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
data: {

    qualifications: [{
        name: '',
        document: ''
    }],

}
,

validations: {

    qualifications: {

        $each: {
            name: {
                required: requiredIf('document')
            }
        ,
            document: {
                required: requiredIf('name')
            }
        }

    }

}
,

methods: {

    qualificationNameErrors(i)
    {
        const errors = [];
        if (!this.$v.qualifications.$each[i].name.$dirty) return errors;
        !this.$v.qualifications.$each[i].name.required && errors.push('This field is required');
        return errors
    }
,

Like this! Observe this carefully! doing this carefully will save you time.

Next,

The second part is to write the error display code and the most important part here is to introduce a parameter. The parameter here in an index, it helps track that the error is for which iteration and highlights only that specific element. One more thing to note here is computed properties will not work here well with the parameter. The fix is very simple. Move the method to methods.

I figured the following part by looking at $v carefully, hence $v should be observed carefully.

1
this.$v.qualifications.$each[i].name.required
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<v-row style="border: 1px solid lightblue;border-radius: 4px;"
                              v-for="(qualification, index) in qualifications">
                            <v-col cols="12" md="6" class="pa-3">

                                <v-text-field
                                       label="Qualification Name"
                                       filled
                                       v-model="qualification.name"
                                       :error-messages="qualificationNameErrors(index)"
                               ></v-text-field>

                            </v-col>

                            <v-col cols="12" md="6" class="pa-3">
                                <v-file-input label="Upload Qualification"
                                             accept="image/*, .pdf"
                                             :error-messages="qualificationDocumentErrors(index)"
                                             v-model="qualification.document"></v-file-input>
                            </v-col>
<v-row>

Simplify Errors with https://dobromir-hristov.github.io/vuelidate-error-extractor/