How to add a custom error message in vue2-vuetify renderer component

I have developed a custom renderer component using @jsonforms/vue2-vuetify.

I want to add a custom error message that is not part of the schema. Is it possible to update the JSON Forms error object from within a custom renderer component so that the error message can be displayed in the Vuetify component?

Specifically, I want to show the error message “Invalid input” when the user’s entered input doesn’t match any of the values in the dropdown.

Could you please assist? Here’s how my component currently looks:

<template>
  <control-wrapper
    v-bind="controlWrapper"
    :styles="{
      control: {
        root: 'control',
        input: 'input'
      }
    }"
    :is-focused="isFocused"
    :applied-options="appliedOptions">
    <v-hover v-slot="{ hover }">
      <v-combobox
        :id="control.id + '-input'"
        v-disabled-icon-focus
        class="input"
        :disabled="!control.enabled"
        :autofocus="appliedOptions.focus"
        :placeholder="appliedOptions.placeholder"
        :label="computedLabel"
        :hint="control.description"
        :persistent-hint="persistentHint()"
        :required="control.required"
        :error-messages="control.errors"
        :maxlength="appliedOptions.restrict ? control.schema.maxLength : undefined"
        :counter="control.schema.maxLength !== undefined ? control.schema.maxLength : undefined"
        :clearable="hover"
        :value="control.data"
        :items="courts"
        hide-no-data
        v-bind="vuetifyProps('v-combobox')"
        @input="onChange"
        @focus="isFocused = true"
        @blur="isFocused = false" />
    </v-hover>
  </control-wrapper>
</template>

<script>
import { defineComponent, onMounted, ref } from 'vue';
import { rendererProps, useJsonFormsControl } from '@jsonforms/vue2';
import { default as ControlWrapper } from '@jsonforms/vue2-vuetify/src/controls/ControlWrapper.vue';
import { useVuetifyControl } from '@jsonforms/vue2-vuetify/src/util';
import { DisabledIconFocus } from '@jsonforms/vue2-vuetify/src/controls/directives';
import CourtAndAuthorityControlTester from './CourtAndAuthorityControlTester';
import { caseAPI } from '../../../api';

const CourtAndAuthorityControl = defineComponent({
  name: 'CourtAndAuthorityControl',
  directives: {
    DisabledIconFocus
  },
  components: {
    ControlWrapper
  },
  props: {
    ...rendererProps()
  },
  setup(props) {
    const vuetifyControl = useVuetifyControl(useJsonFormsControl(props), (value) => value || undefined, 300);

    // state variable for court names
    const courts = ref([]);

    // fetch courts or authorities on component mount
    const fetchCourts = async () => {
      try {
        // path is used to idnetifiy court and authority field
        let { path } = vuetifyControl.control.value;

        let query = {
          query: {
            bool: {
              must: { match_all: {} },
              filter: {
                term: {
                  'type.keyword': path === 'name_court.value' ? 'court' : path === 'authority_name.value' ? 'regular' : ''
                }
              }
            }
          },
          _source: ['name', 'type'],
          from: 0,
          size: 10000 // max size is 10000
        };
        const response = await caseAPI.fetchCourtAndAuthorities(query);
        courts.value = response.hits.map((court) => court._source.name);
      } catch (error) {
        console.error('Failed to fetch courts:', error.message);
      }
    };

    // Fetch courts when component is mounted
    onMounted(fetchCourts);

    return { ...vuetifyControl, courts };
  }
});

export default CourtAndAuthorityControl;

export const entry = {
  tester: CourtAndAuthorityControlTester,
  renderer: CourtAndAuthorityControl
};
</script>

Hi @chandrunaik,

Ideally you make the validation independent of rendering, i.e. perform it outside of the custom renderer. For example you integrate the validation as a custom AJV validator or implement it within a JSON Forms middleware.

To not perform the request multiple times, the communication with your endpoint should be encapsulated into a (cacheable) service which is then used within your renderer and validation integration.

Thank you for your response.