Errors not showing up

I do not understand how to trigger form validation and haven’t found a good example of it.
I have custom renderers, I set validationMode="ValidateAndShow" but my errors array is always empty whatever I type in my fields. I read somewhere on forum that validation is happening on every form change but it doesn’t seen to happen to me.
Is there a specific “Submit” button or method that would trigger the validation?
I can trigger “minLength” error but, how do I trigger err when required field wasn’t touched?

Here’s my form

export function AssetConnectionForm() {
  const [data, setData] = useState({})
  console.log("AssetConnectionForm", data)

  return (
    <JsonForms
      schema={(SQLOSSSchema as unknown) as JsonSchema7}
      uischema={SQLUISchema}
      uischemas={[TableAssetUISchemaRegistryEntry, SplitterUISchemaRegistryEntry]}
      data={data}
      onChange={({ data }) => setData(data)}
      cells={[...cellRegistryEntries]}
      renderers={[...rendererRegistryEntries, ConnectionStringRegistryEntry]}
      validationMode="ValidateAndShow"
    />
  )
}

This is my TextControl

function TextControl({ label, visible, required, data, handleChange, path, errors }: TextControlProps) {
  console.log("TextControl", {  errors }) // always empty
  return !visible ? null : (
    <Form.Item label={label} name={label} rules={[{ required, message: required ? `${label} is required` : "" }]}>
      <Input value={data} onChange={(e) => handleChange(path, e.target.value)} />
    </Form.Item>
  )
}

Hi @elenajdanova,

Yes, this is correct. Validation is always done automatically for you, except if validationMode="NoValidation" is handed over. The validation is form wide. During rendering, the determined errors are handed over to the respective controls. Maybe this fails for your use case.

Can you post the schema, uischema, and uischemas so we can reproduce the issue? Please also post the integration code for the TextControl, i.e. the accompanying tester and how it’s registered in the form.

tested that with commented out uiSchemas it works the same
short version of JsonSchema, cause its too long

export const SQLOSSSchema = {
  "title": "SQLDatasource",
  "description": "--Public API--",
  "type": "object",
  "properties": {
    "type": {
      "title": "Type",
      "default": "sql",
      "enum": ["sql"],
      "type": "string"
    },
    "name": {
      "title": "Name",
      "type": "string",
      "minLength": 3, //this triggers the error to pop up
    },
    "id": {
      "title": "Id",
      "description": "Datasource id",
      "type": "string",
      "format": "uuid"
    },
    "assets": {
      "title": "Assets",
      "default": [],
      "type": "array",
      "items": {
        "anyOf": [
          {
            "$ref": "#/definitions/TableAsset"
          },
          {
            "$ref": "#/definitions/QueryAsset"
          }
        ]
      }
    },
    "connection_string": {
      "title": "Connection String",
      "anyOf": [
        {
          "type": "string",
          "writeOnly": true,
          "format": "password"
        },
        {
          "type": "string"
        }
      ]
    },
"required": ["name", "connection_string"], // this doesn't trigger error
}

uiSchema

import { SQLOSSSchema } from "../oss-schemas/sql"
import { FromSchema } from "json-schema-to-ts"
import { UISchema } from "./ui-schema"
import { RuleEffect } from "@jsonforms/core"

export type SQLFormData = FromSchema<typeof SQLOSSSchema>

export const SQLUISchema: UISchema = {
  type: "Categorization",
  elements: [
    {
      type: "Category",
      label: "Datasource",
      elements: [
        {
          type: "VerticalLayout",
          elements: [
            {
              type: "Control",
              scope: "#/properties/type",
              rule: {
                effect: RuleEffect.HIDE,
                condition: {},
              },
            },
            {
              type: "Control",
              scope: "#/properties/name",
            },
            {
              type: "Control",
              scope: "#/properties/connection_string",
            },
          ],
        },
      ],
    },
    {
      type: "Category",
      label: "Asset",
      elements: [
        {
          type: "Control",
          scope: "#/properties/assets",
          elements: [],
        },
      ],
    },
  ],
}

full textControl

import { withJsonFormsControlProps } from "@jsonforms/react"
import { ControlProps, JsonFormsRendererRegistryEntry, isStringControl, rankWith } from "@jsonforms/core"
import { Input, Form } from "antd"

export const TextControlRegistryEntry: JsonFormsRendererRegistryEntry = {
  tester: (uischema, schema, context) => {
    const rank = rankWith(1, isStringControl)(uischema, schema, context)
    // console.log("TextControl Tester", { rank, uischema, schema, context })

    return rank
  },
  renderer: withJsonFormsControlProps(TextControl),
}
interface TextControlProps extends ControlProps {
  data: string
  handleChange(path: string, value: any): void
  path: string
}

function TextControl({ label, visible, required, data, handleChange, path, errors }: TextControlProps) {
  console.log("TextControl", {  errors })
  return !visible ? null : (
    <Form.Item label={label} name={label} rules={[{ required, message: required ? `${label} is required` : "" }]}>
      <Input value={data} onChange={(e) => handleChange(path, e.target.value)} />
    </Form.Item>
  )
}

Hi @elenajdanova,

The required seems to be at the wrong level, it needs to be specified next to the properties, not within it. For me the following schema

{
  "type": "object",
  "definitions": {
    "TableAsset": { "type": "string" },
    "QueryAsset": { "type": "string" }
  },
  "properties": {
    "type": {
      "title": "Type",
      "default": "sql",
      "enum": ["sql"],
      "type": "string"
    },
    "name": {
      "title": "Name",
      "type": "string",
      "minLength": 3
    },
    "id": {
      "title": "Id",
      "description": "Datasource id",
      "type": "string",
      "format": "uuid"
    },
    "assets": {
      "title": "Assets",
      "default": [],
      "type": "array",
      "items": {
        "anyOf": [
          {
            "$ref": "#/definitions/TableAsset"
          },
          {
            "$ref": "#/definitions/QueryAsset"
          }
        ]
      }
    },
    "connection_string": {
      "title": "Connection String",
      "anyOf": [
        {
          "type": "string",
          "writeOnly": true,
          "format": "password"
        },
        {
          "type": "string"
        }
      ]
    }
  },
  "required": ["name", "connection_string"]
}

renders the following UI

I’m sorry, It is next to “properties” in my schema. So everything is ok. I was just trying to cut the schema itself cause it’s huge and fat-fingered required to show it’s in place. So that’s not the issue.
Do you have a sandbox where you ran my schemas?

I’m using the JSON Forms react seed. If you can set up a reproducible example in a fork of the seed, that would be helpful.