rjsf-team / react-jsonschema-form

A React component for building Web forms from JSON Schema.
https://rjsf-team.github.io/react-jsonschema-form/
Apache License 2.0
14.36k stars 2.19k forks source link

Support custom error messages from schema #4119

Open Rozamo opened 8 months ago

Rozamo commented 8 months ago

Prerequisites

What theme are you using?

validator-ajv8

Is your feature request related to a problem? Please describe.

Forms should be user friendly and so should be the errors. Therefore in cases where the form creator wants to have more readable errors for fields they should be allowed to do so.

For example, if a form is asking for a name and is requiring a pattern ^([^0-9]*)$, the current error shown in must match pattern "^([^0-9]*)$". The creator of form might want to show a custom error like Name should not contain numbers.

Adding support for this would enable more user friendly forms. This is handy when the schema comes from the backend and the UI just renders it.

I think this was being discussed before here.

Describe the solution you'd like

Some implementation using ajv-errors or transformErrors.

Describe alternatives you've considered

Support for custom error messages is present but it has to be driven through code. For the use cases where the schema is coming from the backend there is no way to know the error message before hand.

nickgros commented 8 months ago

@Rozamo have you tried to use ajv-errors in your own code with customizeValidator? We have an example for ajv-keywords, which is very similar:

See Using the raw Ajv instance in the docs.

Rozamo commented 8 months ago

@nickgros Thanks, this worked. This plugin architecture is great! Attaching the code here for future references.


import Form from "@rjsf/core";
import { RJSFSchema } from "@rjsf/utils";
import { customizeValidator } from "@rjsf/validator-ajv8";
import ajvErrors from "ajv-errors";

const validator = customizeValidator();
ajvErrors(validator.ajv);

const schema: RJSFSchema = {
  type: "object",
  properties: {
    name: {
      type: "string",
      title: "Name",
      pattern: "^([^0-9]*)$",
      minLength: 3,
      errorMessage: {
        pattern: "Name must not contain numbers",
        minLength: "Name must be at least 3 characters",
      },
    },
  },
};

const App = () => {
  return <Form schema={schema} validator={validator} />;
};

export default App;