Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Validate form input fields in child component from a parent component with Vuelidate

I am new to Vue Js and Vuelidate. Just tried to validate form input fields from a parent component like here: https://github.com/monterail/vuelidate/issues/333

Child component in the parent:

<contact-list ref="contactList" :contacts="contacts" @primaryChanged="setPrimary" @remove="removeContact" @ready="isReady => readyToSubmit = isReady"/>

The method in the child:

computed: {
    ready() {
        return !this.$v.email.$invalid;
    }
},
watch: {
    ready(val) {
        this.$emit('ready', val);
    }
},

methods: {
    touch() {
        this.$v.email.$touch();
    }
}

I'm calling the touch() method from the parent like so:

submit() {
            this.$refs.contactList.touch();
        },

But I get this error:

Error in event handler for "click": "TypeError: this.$refs.contactList.touch is not a function".

Any ideas? Thanks.

like image 795
kewin123 Avatar asked Nov 17 '22 20:11

kewin123


1 Answers

I was facing the same problem. Here is what I have done to solve it.

  1. Created a global event pool. Where I can emit events using $emit and my child can subscribe using $on or $once and unsubscribe using $off. Inside your app.js paste the below code. Below is the list of event pool actions.

    • Emit: this.$eventPool.$emit()
    • On: this.$eventPool.$on()
    • Off: this.$eventPool.$off()
    • once: this.$eventPool.$once()

Vue.prototype.$eventPool = new Vue();

  1. Inside my child components, I have created a watch on $v as below. Which emits the status of the form to the parent component.
watch: {
    "$v.$invalid": function() {
      this.$emit("returnStatusToParent", this.$v.$invalid);
    }
  }
  1. Now inside you parent component handle the status as below.

<ChildComponent @returnStatusToParent="formStatus =>isChildReady=formStatus"></ChildComponent>

  1. Now to display the proper errors to the users we will $touch the child form. For that, we need to emit an event in the above-created event pool and our child will subscribe to that.

parent:

this.$eventPool.$emit("touchChildForm");

child:

 mounted() {
    this.$eventPool.$on("touchChildForm", () => {
      this.$v.$touch();
      this.$emit("returnStatusToParent", this.$v.$invalid);
    });
  },
  destroyed() {
    this.$eventPool.$off("touchChildForm", () => `{});`
  }

Hope it helps :)

like image 197
Parth Patel Avatar answered Nov 19 '22 09:11

Parth Patel