react-admin ≥ 4.10.6

ra-json-schema-form

Building forms out of a JSON schema.

Test it live in the Enterprise Edition Storybook.

Installation

npm install --save @react-admin/ra-json-schema-form
# or
yarn add @react-admin/ra-json-schema-form

Tip: ra-json-schema-form is part of the React-Admin Enterprise Edition, and hosted in a private npm registry. You need to subscribe to one of the Enterprise Edition plans to access this package.

Warning: This package comes with an additional dependency on the @rjsf/material-ui package . It turns out that this package uses an uncommon import practice, which forces to tweak the TypeScript and Jest configuration, as explained in their docs: https://github.com/rjsf-team/react-jsonschema-form/tree/master/packages/material-ui#material-ui-version-5-1

You will need to add the following to your tsconfig.json

{
    ...
    "compilerOptions": {
        ...
        "baseUrl": ".",
        "paths": {
            "@rjsf/material-ui/*": ["node_modules/@rjsf/material-ui/dist/*"]
        }
    }
}

And add the following to your jest.config.js

{
    "moduleNameMapper": {
        "@rjsf/material-ui/v5": "<rootDir>/node_modules/@rjsf/material-ui/dist/v5.js"
    },
}

Usage

If you have a JSON Schema description of your form based on react-jsonschema-form, you can use the <JsonSchemaForm> component to render it.

For instance, to generate the following form:

json schema form

Configure the <Edit> view with a <JsonSchemaForm> child as follows:

import { Edit } from "react-admin";
import { JsonSchemaForm } from "@react-admin/ra-json-schema-form";

const CustomerEdit = () => (
  <Edit>
    <JsonSchemaForm
      schema={{
        type: "object",
        properties: {
          id: { type: "number" },
          first_name: { type: "string", title: "First name" },
          last_name: { type: "string", minLength: 3 },
          dob: { type: "string", format: "date" },
          sex: { type: "string", enum: ["male", "female"] },
          employer_id: { type: "number" },
          occupations: {
            type: "array",
            items: {
              type: "object",
              properties: {
                name: { type: "string" },
                from: { type: "string", format: "date" },
                to: { type: "string", format: "date" },
              },
            },
          },
        },
        required: ["id", "last_name", "employer_id"],
      }}
      uiSchema={{
        id: { "ui:disabled": true },
        employer_id: {
          "ui:widget": "reference",
          "ui:options": {
            reference: "employers",
            optionText: "name",
          },
        },
      }}
      onChange={(change) =>
        process.env.NODE_ENV !== "test" && console.log("changed", change)
      }
      onError={(error) =>
        process.env.NODE_ENV !== "test" && console.log("error", error)
      }
    />
  </Edit>
);
import { Edit } from "react-admin";
import { JsonSchemaForm } from "@react-admin/ra-json-schema-form";

const CustomerEdit = () => (
  <Edit>
    <JsonSchemaForm
      schema={{
        type: "object",
        properties: {
          id: { type: "number" },
          first_name: { type: "string", title: "First name" },
          last_name: { type: "string", minLength: 3 },
          dob: { type: "string", format: "date" },
          sex: { type: "string", enum: ["male", "female"] },
          employer_id: { type: "number" },
          occupations: {
            type: "array",
            items: {
              type: "object",
              properties: {
                name: { type: "string" },
                from: { type: "string", format: "date" },
                to: { type: "string", format: "date" },
              },
            },
          },
        },
        required: ["id", "last_name", "employer_id"],
      }}
      uiSchema={{
        id: { "ui:disabled": true },
        employer_id: {
          "ui:widget": "reference",
          "ui:options": {
            reference: "employers",
            optionText: "name",
          },
        },
      }}
      onChange={(change) =>
        process.env.NODE_ENV !== "test" && console.log("changed", change)
      }
      onError={(error) =>
        process.env.NODE_ENV !== "test" && console.log("error", error)
      }
    />
  </Edit>
);

<JsonSchemaForm> initializes the form with the current record, and renders it like <SimpleForm> does.

It expects a schema prop describing the expected data shape, and a uiSchema prop describing the UI.

<JsonSchemaForm> is a wrapper around JsonSchema Form's <Form> component, so please refer to JsonSchema Form's documentation for detailed usage.

<JsonSchemaForm> comes with the following UI widgets:

For boolean fields:

  • checkbox (default)
  • radio
  • select

For string fields:

  • text (default)
  • textarea
  • password
  • color

The built-in string field also supports the JSON Schema format property, and will render an appropriate widget accordingly:

  • email: An input[type=email] element is used;
  • uri: An input[type=url] element is used;
  • data-url: By default, an input[type=file] element is used; in case the string is part of an array, multiple files will be handled automatically .
  • date: By default, an input[type=date] element is used;
  • date-time: By default, an input[type=datetime-local] element is used.

For number and integer fields:

  • text (default)
  • updown
  • range
  • radio

ra-json-schema-form comes with the an additional UI widget for string fields: reference. It's the equivalent of react-admin's <ReferenceInput> component. It fetches the foreign key, and uses a relationship to populate the list of options.

Specify the reference, optionText, and other options through the ui:options UI schema directive:

import { Edit } from "react-admin";
import { JsonSchemaForm } from "@react-admin/ra-json-schema-form";

const CustomerEdit = () => (
  <Edit>
    <JsonSchemaForm
      schema={{
        type: "object",
        properties: {
          id: { type: "number" },
          employer_id: { type: "number" },
        },
      }}
      uiSchema={{
        employer_id: {
          "ui:widget": "reference",
          "ui:options": {
            reference: "employers",
            optionText: "name",
          },
        },
      }}
    />
  </Edit>
);
import { Edit } from "react-admin";
import { JsonSchemaForm } from "@react-admin/ra-json-schema-form";

const CustomerEdit = () => (
  <Edit>
    <JsonSchemaForm
      schema={{
        type: "object",
        properties: {
          id: { type: "number" },
          employer_id: { type: "number" },
        },
      }}
      uiSchema={{
        employer_id: {
          "ui:widget": "reference",
          "ui:options": {
            reference: "employers",
            optionText: "name",
          },
        },
      }}
    />
  </Edit>
);

CHANGELOG

v1.1.0

2023-05-24

  • Upgraded to react-admin 4.10.6

v1.0.2

2022-10-17

  • Fix ability to use JsonSchemaForm in a Create view

v1.0.1

2022-08-29

  • Added missing .npmrc file to package

v1.0.0

2022-08-25

  • First release