JSONForms is not picking up changes in custom Vue3 non-string control renderers

Hi,

I’m trying to port the vue-vanilla renderers to use PrimeVue components. I’m binding control.data to the component’s v-model. This works for string and boolean properties in the schema, but fails for numbers (and dates, times). Whenever I change the value in the integer input, the components modelValue changes accordingly (verified in Vue’s Dev tools), but this does not seem to get propagated to jsonform’s data.

Why is this approach working for strings and booleans, but is it failing for numbers and dates?

Below is the code of the IntegerControlRenderer. Some other functioning and non-functioning custom renderers can be viewed with the links in the previous paragraphs, and the complete code is available on GitHub, but only few renderers have been ported.

<script lang="ts">
import {
    ControlElement,
    JsonFormsRendererRegistryEntry,
    rankWith,
    isIntegerControl,
} from "@jsonforms/core";
import { defineComponent } from "vue";
import { rendererProps, useJsonFormsControl, RendererProps } from "@jsonforms/vue";
import { default as ControlWrapper } from "./ControlWrapper.vue";
import { useVanillaControl } from "../util";

import InputNumber from "primevue/inputnumber";


const controlRenderer = defineComponent({
    name: "IntegerControlRenderer",
    components: {
        ControlWrapper,
    },
    props: {
        ...rendererProps<ControlElement>(),
    },
    setup(props: RendererProps<ControlElement>) {
        return useVanillaControl(
            useJsonFormsControl(props), 
            (target) => target.value === "" ? undefined : Number(target.value)
        );
    },
    methods: {
        onChange(value){
            console.log(value)
        }
    },
});

export default controlRenderer;

export const entry: JsonFormsRendererRegistryEntry = {
    renderer: controlRenderer,
    tester: rankWith(1, isIntegerControl),
};
</script>

<template>
    <control-wrapper
        v-bind="controlWrapper"
        :styles="styles"
        :is-focused="isFocused"
        :applied-options="appliedOptions"
    >
        <InputNumber
            v-model="control.data"
            :id="control.id + '-input'"
            inputId="integeronly"
            showButtons
            fluid
            :step="1"
            :class="styles.control.input"
            :disabled="!control.enabled"
            :autofocus="appliedOptions.focus"
            :placeholder="appliedOptions.placeholder"
            @change="onChange"
            @focus="isFocused = true"
            @blur="isFocused = false"
        />
    </control-wrapper>
</template>

Hi @kobbejager,

In JSON Forms we do not use v-model. Instead we have a reducer based approach which is managed through the control.data and onChange bindings, see for example here.

Hi.
Thnaks for your answer. This was indeed the approach that I used at first, and it works fine for the StringControlRenderer. In the IntegerControlRenderer (and others), the control doesn’t do anything if use :value="control.data" and @change="onChange" (without any v-model). I type in a number+tab, number is gone from the input, onChange() is not called and my form data object is not updated. The Vuetify renderers seem to use a more complex approach using @input, but I don’t quite understand what is happening here and what the Vuetify renderers are doing.