Unable to change the value on TextField when using ajv.addFormat

Hello,
I am retrieving data.json from backend API and populating the values on CustomTextfield.
when I add below validation, validation is to check if value is a positive integer it is not letting me to change the values on text field.
const ajv = createAjv({ strict: false, allErrors: true, useDefaults: true });
ajv.addFormat(“validateAll”, { type: “string”, validate: (x: any) => x !== “” && !isNaN(x) && parseInt(x) >= 0 });

can you please guide me on how to enable user to change the input field and display error when format validation fails?

Hi @Akhil,

typically the validation is performed after the data was changed through an input. Thus, it seems likely that there is another problem leading to the user not being able to change the input field.
Could you provide more context/code how you use your CustomTextfield?
Best regards,
Lucas

Hi Lucas,
Thanks for the reply, I
Below is how I am using custom renderer for text field.

InputField.tsx:

import * as React from "react";
import { rankWith, uiTypeIs } from "@jsonforms/core";
import { withJsonFormsControlProps } from "@jsonforms/react";
import { TextField } from "@mui/material";
import "./inputField.scss";

export const InputFieldTester = rankWith(1000, uiTypeIs("inputField"));

function InputFieldRenderer(props: any) {
  const { handleChange } = props;

  const applyCssChanges = (e: any) => {
    const minimum = props.schema.minimum;
    const maximum = props.schema.maximum;

    const switchComponent =
      e.target.parentElement.parentElement.parentElement.parentElement
        .children[0];
    if (
      props.errors != ""
      // e.target.value < minimum ||
      // e.target.value > maximum
    ) {
      switchComponent.style.marginBottom = "10%";
    } else {
      switchComponent.style.marginBottom = "0";
    }
  };
  const handleInputChange = (e: any) => {
    if (props.schema.minimum != null) {
      console.log("props in input field renderer", props);
      applyCssChanges(e);
    }
    let { value } = e.target;
    // value = isNaN(value) ? 0 : value;
    if (props.schema.type === "number") {
      value = Number(value);
    }
    handleChange(props.path, value);
  };

  return (
    <>
      <TextField
        error={props.errors ? true : false}
        helperText={props.errors ? props.errors : null}
        type={props.schema.type === "string" ? "text" : props.schema.type}
        id="outlined-basic-custom"
        variant="outlined"
        disabled={props.enabled}
        onChange={handleInputChange}
        value={props.data}
      />
      <span> {props.schema.label} </span>
    </>
  );
}
export default withJsonFormsControlProps(InputFieldRenderer);
  • To validate string data, i added below code in tsx file
    ajv.addFormat("validateAll", { type: "string", validate: (x: any) => x !== "" && !isNaN(x) && parseInt(x) >= 0 });

  • added format in schema.json file

 {
  "type": "object",
  "properties": {
      "WeeklyExecutionSlots": {
          "type": "object",
          "properties": {
              
              "LE_upper_placement_limit": {
                  "type": "string",
                  "format": "validateAll"

              },
		  }
	  }
  }
}

Hi @Akhil,

We don’t block any writes in regards to AJV, so if there is no Javascript crash the write should always go through.

Looking at the code the disabled prop seems to be wrongly set, i.e. it should be disabled={!props.enabled} instead of disabled={props.enabled}.

Not directly related but you should always hand over a default value to any Material UI input as otherwise there might be some unexpected un/controled switch at runtime, e.g. value={props.data ?? props.schema.type === 'string' ? '' : 0}. On another note I would recommend implementing different controls for the different types instead of handling all cases within a single renderer. This would for example avoid the ternary above and the parsing code in your example.