4

I am using Laravel Nova and have created a custom Field, that gets company info via an api service. This works just fine. Where I am stuck, is when the company data returns I want to fill the rest of the resource form fields with this data. I am almost there, but my Vue skills are not great.

So I created a vue method that is called when the user selects company from the select field. I can send the values, but I am not able to edit the other field vue components and therefore not able to add listeners. Can I update those fields simply by passing the data from the custom field?

fillInputFields (selectedCompanyData) {
    this.$parent.$children.forEach(component => {
         if (component.field !== undefined && component.field.attribute == 'name') {
              component.field.value = selectedCompanyData.name
         }
         if (component.field !== undefined && component.field.attribute == 'tax_number') {
              component.field.value = selectedCompanyData.cvr
         }
    })
},

enter image description here

Community
  • 1
  • 1
Vayu Robins
  • 168
  • 1
  • 12

2 Answers2

3

You may want to emit an event and pass data in its payload instead

fillInputFields(selectedCompanyData) {
    this.$parent.$emit("fill-company-data", {
        name: selectedCompanyData.name,
        cvr: selectedCompanyData.cvr
    });
}

And listen to the event in the siblings and update accordingly

using psychic skills to emulate the siblings

mounted() {
    this.$root.$on("fill-company-data", data => {
        this.name = data.name;
        this.tax_number = data.cvr;
    });
}

Hope this helps

Salim Djerbouh
  • 10,719
  • 6
  • 29
  • 61
  • Hi Saly. Thanks so much for helping! The mounted function would go on the other sibling components right? If so, then that is exactly what I can't do. I am not able to edit those files – Vayu Robins Oct 13 '19 at 03:09
  • Why not? They're not binary files – Salim Djerbouh Oct 13 '19 at 03:12
  • I am using Laravel Nova, which is a cms. Each input field type is its own component. I don't wanna change the source code of the system. – Vayu Robins Oct 14 '19 at 07:05
  • Is it not possible to change the value of the other input fields without adding listeners? – Vayu Robins Oct 14 '19 at 07:10
  • You're not "changing" the source code, you're just extending it and yes it's not possible in the Vue data centric way, you can still dive into the DOM and change the value in a JQuery way – Salim Djerbouh Oct 14 '19 at 11:17
  • Ok that sounds great! So admittingly, this is where my Vue skills are lacking, but if I understand the code you added to mounted(), this looks like a listener that is added to the other field components. But maybe I am misunderstanding this? I have tried to add the code to my own custom field, and when I run it I get no response when I console.log it. – Vayu Robins Oct 15 '19 at 08:27
  • 1
    Ok Saly, I got it. `this.$root.$on("fill-company-fields", data => { this.$parent.$children.forEach(component => { if (component.field !== undefined && component.field.attribute == 'name') { component.value = data.name } } }` Thanks so much for helping!! – Vayu Robins Oct 15 '19 at 09:33
0

Thanks for the guidance guys, I was busy working with a google maps API implementation on Laravel Nova 3+ and I wanted to implement something similar.

I have a custom field called "PlacesSearch" inside that components FormField.vue file I have a field input called search which accepts an address, I then populate the address_line_1, etc etc fields based on the return of the API

// In Nova resource

PlacesSearch::make('Search')->onlyOnForms(),

// In FormField.vue - mounted()

Nova.$on("fill-search-fields", (data) => {
  this.$parent.$children.forEach((component) => {
    if(component.field.attribute == 'address_line_1'){
      component.value = data.address_line_1;
    }
  });
});

// In FormField.vue - search() i.e the method I wrote that fetches from the API, but have replaced with text for demo

Nova.$emit("fill-search-fields", {
  address_line_1: 'address line 1',
});
Dharman
  • 30,962
  • 25
  • 85
  • 135