koumoul-dev / vuetify-jsonschema-form

Create beautiful and low-effort forms that output valid data. Published on npm as @koumoul/vjsf.
https://koumoul-dev.github.io/vuetify-jsonschema-form/latest/
MIT License
538 stars 154 forks source link

Bug: Custom components cannot update the model #363

Open Martin-Idel opened 1 year ago

Martin-Idel commented 1 year ago

Suppose you have the following (working) example with custom slots:

<v-app id="app">
  <v-container>
    <p>valid={{valid}}</p>
    <v-form ref="form" v-model="valid">
      <v-jsf
             @input="myCustomInput"
             @change="myCustomChange"
             :value="model"
             :schema="schema"
             >
        <template slot="custom-list" slot-scope="{ value, on }">
          <input :value="value" v-on="on" />
        </template>
      </v-jsf>
    </v-form>
    <v-layout row class="mt-2">
      <v-spacer></v-spacer>
      <v-btn color="primary" @click="$refs.form.validate()">Validate</v-btn>
    </v-layout>
  </v-container>
</v-app>
const model = {
  list_section: "Test"
}

const schema = {
  title: "my_model",
  type: "object",
  properties: {
    list_section: {
        type: "string",
        "x-display": "custom-list",
      }
   }
}

Vue.component('VJsf', VJsf.default)

new Vue({
  el: '#app',
  vuetify: new Vuetify(),
  data: {
    model,
    schema,
    valid: null
  },
  methods: {
    myCustomInput(key, $event) {
      console.log('vjsf event', key, $event)
    },
    myCustomChange(key, $event) {
      console.log('vjsf event', key, $event)
    }
  }
})

This works as expected: Changing the input element emits input signals on keystrokes and a change event on losing focus/enter which would change the model if so implemented.

Now suppose that we change the type of the list_section to object (pretty much irrelevant) and <input :value="value" v-on="on" /> to <my-component :value="value" v-on="on" /> where my-component is a custom Vue component. The component:

Display works as expected: The component can show the model and is displayed as expected. On changing the model, the change event is correctly emitted from the custom-component, however myCustomChange is never triggered. In other words: The changes in the custom component are never reflected back to the model.

I noticed that this seems to be a specific problem with the change event. If I trigger the input event instead, myCustomInput IS called. I also tried the following alternatives:

watterm commented 1 year ago

Same here.

The examples in the docs doesn't bind either function. When I use v-on, the input event from my component changes the model.

<template slot="custom-component" slot-scope="context">
  <custom-component
    v-bind="context"
    v-on="context.on"
  />
</template>
Martin-Idel commented 1 year ago

Thanks for your input. I'll try that, too.

What I figured with my setup was that if I emitted both input and change at the same time, everything worked as expected. Only emitting one of the two - I never got any signal. No idea why that should be the case though...