Json Schema Form

Today we are going to create a form using JSON with the help of a library called react-jsonschema-form.

The package is now called @rjsf/core

What is @rjsf/core?

A simple React component capable of building HTML forms out of a JSON schema.You have varieties of CSS libraries you can use along with this library to make the form beautiful such as antd, bootstrap, materialUI.

Dependencies

You need the install these packages

npm install @rjsf/core @rjsf/utils @rjsf/validator-ajv8 --save

We'll be using antd library for CSS

npm i --save @rjsf/antd antd dayjs

All the dependencies are installed, now let's move directly to making the form out of JSON.

import { withTheme } from "@rjsf/core";
import { Theme as AntDTheme } from '@rjsf/antd';
import { RJSFSchema } from "@rjsf/utils";
import validator from '@rjsf/validator-ajv8';

function Portfolio() {

  const Form = withTheme(AntDTheme);

  const schema: RJSFSchema = {
    title: 'Portfolio form',
    type: 'object',
    required: ['title'],
    definitions: {
       "transactionTypeEnum":{
          "type":"string",
          "enum":["Buy", "Sell"]
       }
    },
    properties: {
      TransactionType: {"$ref": "#/definitions/transactionTypeEnum"},
      Name: { type: 'string', title: 'Title', default: '' },
      Quantity: { type: 'number', title: 'Quantity', default: '' },
      Price: { type: 'number', title: 'Price', default: 'price' },
      TransactionDate: { type: 'string', title: 'TransactionDate', format: 'date' },
    },
  };

  return (
    <div>
        <div id="portfolioForm">
          <Form
            schema={schema}
            validator={validator}
          />
        </div>
    </div>
  );
}
export default Portfolio;

The code is quiet straightforward.

const Form = withTheme(AntDTheme);

We import antDTheme from @rjsf/antd and supply it as a parameter to withTheme function from @rjsf/core. It will return a component that we can use to create the form. That form will use antd them for the form created.

Next we create a JSON schema, it has

  • title : the form's title

  • required: here you can mention what fields you want as required

  • properties : it contains the form input item, you can mention type, default, title, and format for each input type.

  const schema: RJSFSchema = {
    title: 'Portfolio form',
    type: 'object',
    required: ['title'],
    definitions: {
       "transactionTypeEnum":{
          "type":"string",
          "enum":["Buy", "Sell"]
       }
    },
    properties: {
      TransactionType: {"$ref": "#/definitions/transactionTypeEnum"},
      Name: { type: 'string', title: 'Title', default: '' },
      Quantity: { type: 'number', title: 'Quantity', default: '' },
      Price: { type: 'number', title: 'Price', default: 'price' },
      TransactionDate: { type: 'string', title: 'TransactionDate', format: 'date' },
    },
  };

Finally we create the form as

 <Form schema={schema} validator={validator} />

We have provided the required field, the validation has to be done, that's where the library '@rjsf/validator-ajv8' comes into play. We import it and use in the form.

import validator from '@rjsf/validator-ajv8';

Let's check the output