Skip to content
PlaygroundForm Builder

Dynamic forms

Using the following JSON Schema keywords, you can build forms that change in response to user input.

Fields oneOf or anyOf can be used as a virtual selector. This selector does not modify form data directly but determines which schema is active.

When the form is initialized with initialValue, SJSF automatically selects the most suitable schema based on the data.

<script lang="ts">
  import { SimpleForm, type Schema } from "@sjsf/form";

  import * as defaults from "$lib/sjsf/defaults";

  const schema = {
    type: "object",
    properties: {
      common: {
        type: "string",
      },
    },
    oneOf: [
      {
        title: "Foo schema",
        properties: {
          foo: {
            type: "string",
          },
        },
      },
      {
        title: "Bar schema",
        properties: {
          bar: {
            type: "string",
          },
        },
      },
    ],
  } as const satisfies Schema;

  const initialValue = {
    common: "hello",
    bar: "world",
  };
</script>

<SimpleForm {...defaults} {schema} {initialValue} />

The dependencies keyword allows you to declare relationships between fields, where the presence or value of one field affects the schema of others.

<script lang="ts">
  import { SimpleForm, type Schema, type UiSchema } from "@sjsf/form";

  import * as defaults from "$lib/sjsf/defaults";

  const schema = {
    type: "object",
    properties: {
      foo: {
        type: "string",
        description:
          "If you enter anything here then `bar` will become required",
      },
      bar: {
        type: "string",
        description: "If you enter anything here then `baz` will appear",
      },
    },
    dependencies: {
      foo: ["bar"],
      bar: {
        properties: {
          baz: {
            enum: ["string", "number", "boolean"],
            description:
              "If you select anything here, the corresponding field will appear",
          },
        },
      },
      baz: {
        oneOf: [
          {
            properties: {
              baz: {
                const: "string",
              },
              string: {
                type: "string",
              },
            },
          },
          {
            properties: {
              baz: {
                const: "number",
              },
              number: {
                type: "number",
              },
            },
          },
          {
            properties: {
              baz: {
                const: "boolean",
              },
              boolean: {
                type: "boolean",
              },
            },
          },
        ],
      },
    },
  } as const satisfies Schema;

  const uiSchema: UiSchema = {
    baz: {
      "ui:components": {
        stringField: "enumField",
      },
    },
  };
</script>

<SimpleForm {...defaults} {schema} {uiSchema} />

The if/then/else keywords allow you to define conditional schema branches based on form data.

<script lang="ts">
  import { SimpleForm, type Schema } from "@sjsf/form";

  import * as defaults from "$lib/sjsf/defaults";

  const schema = {
    type: "object",
    properties: {
      isCompany: {
        type: "boolean",
        title: "Registering as a company",
      },
    },
    required: ["isCompany"],
    if: {
      properties: {
        isCompany: { const: true },
      },
      required: ["isCompany"],
    },
    then: {
      properties: {
        companyName: {
          type: "string",
          title: "Company name",
        },
      },
      required: ["companyName"],
    },
    else: {
      properties: {
        fullName: {
          type: "string",
          title: "Full name",
        },
      },
      required: ["fullName"],
    },
  } as const satisfies Schema;
</script>

<SimpleForm {...defaults} {schema} />

The patternProperties keyword allows you to define schemas for object properties whose names match a regular expression. This is useful for forms with dynamic keys, such as key-value pairs or metadata fields. See the example for a working demo.