Vuelidate dynamically adding a field to array immediately makes it dirty

43 Views Asked by At

I am working on a vue 3 app with vuelidate next and have some validations that look like this:

validations: {
    currentUser: {
        name: {
            required,
            maxLength: maxLength(64),
        },
        email: {
            required,
            email,
            maxLength: maxLength(64),
        },
        address: {
            maxLength: maxLength(191),
        },
        password: {
            minLength: minLength(8),
            maxLength: maxLength(64),
        },
        alarm_emails: {
            $each: helpers.forEach({
                alarm_email: {
                    required,
                    email,
                    maxLength: maxLength(64),
                }
            })
        },
        phones: {
            $each: helpers.forEach({
                number: {
                    required,
                    phone,
                }
            })
        }
    },
},

and on a click of a button I am adding a new field using this code:

this.currentUser.alarm_emails.push({alarm_email: '', is_alarm: this.currentUser.is_email_alarm });

and this works but the problem is the new field is immediately dirty and I do not want that.

I've been googling for some time and found nothing. I tried:

this.v$.currentUser.$reset();

and similar things but that did not help. I even asked bard about it.

Any ideas?

1

There are 1 best solutions below

3
Mohesn Mahmoudi On

You can manually reset the validation state for that field after adding it. Here's how you can modify your code to achieve this:

this.currentUser.alarm_emails.push({ alarm_email: '', is_alarm: this.currentUser.is_email_alarm });

// Manually reset validation state for the newly added field
const newAlarmEmailIndex = this.currentUser.alarm_emails.length - 1;
this.$nextTick(() => {
    this.$v.currentUser.alarm_emails[newAlarmEmailIndex].$reset();
});

this.$nextTick() is used to ensure that the DOM has been updated after adding the new field before resetting its validation state. This way, the newly added field won't be marked as dirty immediately.

Another solution:

this.currentUser.alarm_emails.push({ alarm_email: '', is_alarm: this.currentUser.is_email_alarm });

const newAlarmEmailIndex = this.currentUser.alarm_emails.length - 1;
const newAlarmEmailValidations = this.$v.currentUser.alarm_emails[newAlarmEmailIndex];
if (newAlarmEmailValidations) {
    for (const key in newAlarmEmailValidations) {
        if (Object.hasOwnProperty.call(newAlarmEmailValidations, key) && key !== '$model') {
            newAlarmEmailValidations[key].$reset();
        }
    }
}