Foundation Forms
foundation-forms
is a library for efficiently building complex forms and filters at scale.
At its simplest, a form is a collection of fields for entering data. However, forms can also be very complex, allowing you to add different web components, such as checkboxes, tabbed information or even steps to guide the user through a process. There are also many layout options for the information in the form.
There are two types of schema that enable you to define the layout and content of a form:
- resourceName or jsonSchema defines the underlying data to be shown in the UI (objects, properties, and their types).
- uiSchema defines how this data is rendered as a form, e.g. the order of controls, their visibility, and the layout.
Examples
Adding a form component to the template
You don't need to create your own schema for the form; this automatically uses the JSON schema
generated by the specified endpoint (which you have defined in your back end).
- Genesis
- React
- Angular
Declaration:
<foundation-form
design-system-prefix="rapid"
resourceName="EVENT_INSERT_USER"
></foundation-form>
Usage:
@customElement({
name: 'form-example',
template: html`
<foundation-form
design-system-prefix="rapid"
resourceName="EVENT_INSERT_USER"
></foundation-form>
`,
})
export class FormExample extends GenesisElement {}
Declaration:
<foundation-form
design-system-prefix="rapid"
resourceName="EVENT_INSERT_USER"
></foundation-form>
Usage:
export default function FormExample({}) {
return (
<foundation-form
design-system-prefix="rapid"
resourceName="EVENT_INSERT_USER"
></foundation-form>
);
}
Declaration
<foundation-form
design-system-prefix="rapid"
resourceName="EVENT_INSERT_USER"
></foundation-form>
Usage
import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { FormsModule } from '@angular/forms';
@Component({
selector: 'my-root',
template: `
<foundation-form
design-system-prefix="rapid"
resourceName="EVENT_INSERT_USER"
></foundation-form>
`,
standalone: true,
schemas: [CUSTOM_ELEMENTS_SCHEMA],
imports: [FormsModule],
})
export class AppComponent {}
Configuring a form using the UI schema
You can configure the appearance of the form using the UI schema (see below).
Here is an example UI schema for configuring a form:
- Genesis
- React
- Angular
Declaration:
<foundation-form
design-system-prefix="rapid"
resourceName="EVENT_INSERT_USER"
:uischema=${(x) => x.uiSchema}
></foundation-form>
Usage:
const uiSchemaExample = {
type: "VerticalLayout",
elements: [
{
type: "Control",
label: "Username",
scope: "#/properties/USER_NAME",
},
{
type: "Control",
label: "Email",
scope: "#/properties/EMAIL",
},
{
type: "Control",
label: "Password",
scope: "#/properties/PASSWORD",
options: {
isPassword: true,
},
},
{
type: "Control",
label: "Password confirmation",
scope: "#/properties/PASSWORD_CONFIRMATION",
options: {
isPassword: true,
},
},
],
};
@customElement({
name: 'form-example',
template: html`
<foundation-form
design-system-prefix="rapid"
resourceName="EVENT_INSERT_USER"
:uischema=${x => uiSchema}
></foundation-form>
`,
})
export class FormExample extends GenesisElement {
uiSchema: UiSchema = uiSchemaExample;
}
Declaration:
<foundation-form
design-system-prefix="rapid"
resourceName="EVENT_INSERT_USER"
uischema={uiSchema}
></foundation-form>
Usage:
const uiSchemaExample = {
type: "VerticalLayout",
elements: [
{
type: "Control",
label: "Username",
scope: "#/properties/USER_NAME",
},
{
type: "Control",
label: "Email",
scope: "#/properties/EMAIL",
},
{
type: "Control",
label: "Password",
scope: "#/properties/PASSWORD",
options: {
isPassword: true,
},
},
{
type: "Control",
label: "Password confirmation",
scope: "#/properties/PASSWORD_CONFIRMATION",
options: {
isPassword: true,
},
},
],
};
export default function FormExample({}) {
const uiSchema: UiSchema = uiSchemaExample;
return (
<foundation-form
design-system-prefix="rapid"
resourceName="EVENT_INSERT_USER"
uischema={uiSchema}
></foundation-form>
);
}
Declaration
<foundation-form
design-system-prefix="rapid"
resourceName="EVENT_INSERT_USER"
[uischema]="uiSchema"
></foundation-form>
Usage
import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { FormsModule } from '@angular/forms';
const uiSchemaExample = {
type: "VerticalLayout",
elements: [
{
type: "Control",
label: "Username",
scope: "#/properties/USER_NAME",
},
{
type: "Control",
label: "Email",
scope: "#/properties/EMAIL",
},
{
type: "Control",
label: "Password",
scope: "#/properties/PASSWORD",
options: {
isPassword: true,
},
},
{
type: "Control",
label: "Password confirmation",
scope: "#/properties/PASSWORD_CONFIRMATION",
options: {
isPassword: true,
},
},
],
};
@Component({
selector: 'my-root',
template: `
<foundation-form
design-system-prefix="rapid"
resourceName="EVENT_INSERT_USER"
[uischema]="uiSchema"
></foundation-form>
`,
standalone: true,
schemas: [CUSTOM_ELEMENTS_SCHEMA],
imports: [FormsModule],
})
export class AppComponent {
uiSchema = uiSchemaExample
}
Configuring a form using a JSON schema (client-side)
Instead of providing resourceName, you can hard-code the JSON schema on the client.
Use this when you want to avoid fetching metadata from the server, but be aware that it could get out of sync if metadata changes on the server.
Here is an example of a JSON schema:
- Genesis
- React
- Angular
Declaration:
<foundation-form
design-system-prefix="rapid"
resourceName="EVENT_INSERT_USER"
:uischema=${(x) => x.uiSchema}
:jsonSchema=${(x) => x.jsonSchema}
></foundation-form>
Usage:
const uiSchemaExample = {
type: "VerticalLayout",
elements: [
{
type: "Control",
label: "Username",
scope: "#/properties/USER_NAME",
},
{
type: "Control",
label: "Email",
scope: "#/properties/EMAIL",
},
{
type: "Control",
label: "Password",
scope: "#/properties/PASSWORD",
options: {
isPassword: true,
},
},
{
type: "Control",
label: "Password confirmation",
scope: "#/properties/PASSWORD_CONFIRMATION",
options: {
isPassword: true,
},
},
],
};
export const jsonSchemaExample = {
type: 'object',
properties: {
SIDE: {
type: 'string',
description: 'kotlin.String',
},
QUANTITY: {
type: 'number',
description: 'kotlin.Double',
},
SIMPLE_TRADE_ID: {
type: 'string',
description: 'kotlin.String',
}
}
};
@customElement({
name: 'form-example',
template: html`
<foundation-form
design-system-prefix="rapid"
resourceName="EVENT_INSERT_USER"
:uischema=${(x) => uiSchema}
:jsonSchema=${(x) => jsonSchema}
></foundation-form>
`,
})
export class FormExample extends GenesisElement {
uiSchema: UiSchema = uiSchemaExample;
jsonSchema: JSONSchema7 = jsonSchemaExample;
}
Declaration:
<foundation-form
design-system-prefix="rapid"
resourceName="EVENT_INSERT_USER"
uischema={uiSchema}
jsonSchema={jsonSchema}
></foundation-form>
Usage:
const uiSchemaExample = {
type: "VerticalLayout",
elements: [
{
type: "Control",
label: "Username",
scope: "#/properties/USER_NAME",
},
{
type: "Control",
label: "Email",
scope: "#/properties/EMAIL",
},
{
type: "Control",
label: "Password",
scope: "#/properties/PASSWORD",
options: {
isPassword: true,
},
},
{
type: "Control",
label: "Password confirmation",
scope: "#/properties/PASSWORD_CONFIRMATION",
options: {
isPassword: true,
},
},
],
};
export const jsonSchemaExample = {
type: 'object',
properties: {
SIDE: {
type: 'string',
description: 'kotlin.String',
},
QUANTITY: {
type: 'number',
description: 'kotlin.Double',
},
SIMPLE_TRADE_ID: {
type: 'string',
description: 'kotlin.String',
}
}
};
export default function FormExample({}) {
const uiSchema: UiSchema = uiSchemaExample;
const jsonSchema: JSONSchema7 = jsonSchemaExample;
return (
<foundation-form
design-system-prefix="rapid"
resourceName="EVENT_INSERT_USER"
uischema={uiSchema}
jsonSchema={jsonSchema}
></foundation-form>
);
}
Declaration
<foundation-form
design-system-prefix="rapid"
resourceName="EVENT_INSERT_USER"
[uischema]="uiSchema"
[jsonSchema]="jsonSchema"
></foundation-form>
Usage
import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { FormsModule } from '@angular/forms';
const uiSchemaExample = {
type: "VerticalLayout",
elements: [
{
type: "Control",
label: "Username",
scope: "#/properties/USER_NAME",
},
{
type: "Control",
label: "Email",
scope: "#/properties/EMAIL",
},
{
type: "Control",
label: "Password",
scope: "#/properties/PASSWORD",
options: {
isPassword: true,
},
},
{
type: "Control",
label: "Password confirmation",
scope: "#/properties/PASSWORD_CONFIRMATION",
options: {
isPassword: true,
},
},
],
};
export const jsonSchemaExample = {
type: 'object',
properties: {
SIDE: {
type: 'string',
description: 'kotlin.String',
},
QUANTITY: {
type: 'number',
description: 'kotlin.Double',
},
SIMPLE_TRADE_ID: {
type: 'string',
description: 'kotlin.String',
}
}
};
@Component({
selector: 'my-root',
template: `
<foundation-form
design-system-prefix="rapid"
resourceName="EVENT_INSERT_USER"
[uischema]="uiSchema"
[jsonSchema]="jsonSchema"
></foundation-form>
`,
standalone: true,
schemas: [CUSTOM_ELEMENTS_SCHEMA],
imports: [FormsModule],
})
export class AppComponent {
uiSchema = uiSchemaExample;
jsonSchema = jsonSchemaExample;
}
Pre-filling a form with data (optional)
The data attribute allows you to pre-fill the form with information. A common use case for this is when editing an existing record.
- Genesis
- React
- Angular
Declaration:
<foundation-form
design-system-prefix="rapid"
resourceName="EVENT_INSERT_USER"
:data=${(x) => x.data}
></foundation-form>
Usage:
const existingData = {
USER_NAME: "Genesis",
EMAIL: "example@genesis.global",
PASSWORD: "secret_password",
PASSWORD_CONFIRMATION: "secret_password",
};
@customElement({
name: 'form-example',
template: html`
<foundation-form
design-system-prefix="rapid"
resourceName="EVENT_INSERT_USER"
:data=${(x) => x.data}
></foundation-form>
`,
})
export class FormExample extends GenesisElement {
data = existingData;
}
Declaration:
<foundation-form
design-system-prefix="rapid"
resourceName="EVENT_INSERT_USER"
data={data}
></foundation-form>
Usage:
const existingData = {
USER_NAME: "Genesis",
EMAIL: "example@genesis.global",
PASSWORD: "secret_password",
PASSWORD_CONFIRMATION: "secret_password",
};
export default function FormExample({}) {
const data = existingData;
return (
<foundation-form
design-system-prefix="rapid"
resourceName="EVENT_INSERT_USER"
data={data}
></foundation-form>
);
}
Declaration
<foundation-form
design-system-prefix="rapid"
resourceName="EVENT_INSERT_USER"
[data]="data"
></foundation-form>
Usage
import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { FormsModule } from '@angular/forms';
const existingData = {
USER_NAME: "Genesis",
EMAIL: "example@genesis.global",
PASSWORD: "secret_password",
PASSWORD_CONFIRMATION: "secret_password",
};
@Component({
selector: 'my-root',
template: `
<foundation-form
design-system-prefix="rapid"
resourceName="EVENT_INSERT_USER"
[data]="data"
></foundation-form>
`,
standalone: true,
schemas: [CUSTOM_ELEMENTS_SCHEMA],
imports: [FormsModule],
})
export class AppComponent {
data = existingData
}
After you have looked at the basics here, you can find more details in our API Docs
Full source code at Forms introduction