Basic uniforms usage
You can also follow the tutorial and explore uniforms in our sample CodeSandbox repository.
Imagine that we host an IT conference and want to make a list of guests. Obviously, we want to collect their first name and last name. Additionally, we can ask for their work experience, but that information is not required. Let's prepare a form for the guests, so they can sign up for our event, by using uniforms!
1. Install the required packages
To start using uniforms, we have to install three independent packages:
- Core
- Bridge
- Theme
In this example, we will use the JSONSchema to describe our desired data format and style our form using Semantic UI theme.
npm install uniforms
npm install uniforms-bridge-json-schema
npm install uniforms-semantic
Note: When using a themed package, remember to include correct styles! If you are willing to run this example by yourself, have a read on Semantic UI React's theme usage.
2. Start by defining a schema
After we've installed required packages, it's time to define our Guest schema. We can do it in a plain JSON, which is a valid JSONSchema instance:
import Ajv, { JSONSchemaType } from 'ajv';
type FormData = {
firstName: string;
lastName: string;
workExperience: number;
};
const schema: JSONSchemaType<FormData> = {
title: 'Guest',
type: 'object',
properties: {
firstName: { type: 'string' },
lastName: { type: 'string' },
workExperience: {
description: 'Work experience in years',
type: 'integer',
minimum: 0,
maximum: 100,
},
},
required: ['firstName', 'lastName'],
};
As you can see, we've defined three properties - firstName
and lastName
, that are of string type, and workExperience
,
which is an integer, with a value between 0 and 100.
3. Then create the bridge
Now that we have the schema, we can create the uniforms bridge of it, by using the corresponding uniforms schema-to-bridge package.
Creating the bridge instance is necessary - without it, uniforms would not be able to process form generation and validation.
As we are using the JSONSchema, we have to import the uniforms-bridge-json-schema
package.
import { JSONSchemaBridge } from 'uniforms-bridge-json-schema';
Now you may think that we can simply do:
// Wrong usage of the JSONSchemaBridge!
// You have to pass a validator!
const bridge = new JSONSchemaBridge({ schema });
However, there's small caveat with using the JSONSchemaBridge.
Because of its simplicity, JSONSchema doesn't provide any validation checkers, so in order to properly validate our submitted data,
we need to manually define a validator, and that is required by the uniforms JSONSchemaBrigde
constructor.
To manually create the validator, we will use the Ajv package:
Ajv executes in strict mode by default since version 7. To avoid errors at schema compilation phase, we have to register the uniforms
keyword (see Unknown keywords for more details).
import Ajv, { JSONSchemaType } from 'ajv';
const ajv = new Ajv({
allErrors: true,
useDefaults: true,
keywords: ['uniforms'],
});
function createValidator<T>(schema: JSONSchemaType<T>) {
const validator = ajv.compile(schema);
return (model: Record<string, unknown>) => {
validator(model);
return validator.errors?.length ? { details: validator.errors } : null;
};
}
const schemaValidator = createValidator(schema);
Now that we have both the schema and the validator, we can create the uniforms bridge:
// Correct usage of the JSONSchemaBridge.
export const bridge = new JSONSchemaBridge({
schema,
validator: schemaValidator,
});
Just to recap, the whole GuestSchema.js
file looks like this:
import Ajv, { JSONSchemaType } from 'ajv';
import { JSONSchemaBridge } from 'uniforms-bridge-json-schema';
type FormData = {
firstName: string;
lastName: string;
workExperience: number;
};
const schema: JSONSchemaType<FormData> = {
title: 'Guest',
type: 'object',
properties: {
firstName: { type: 'string' },
lastName: { type: 'string' },
workExperience: {
description: 'Work experience in years',
type: 'integer',
minimum: 0,
maximum: 100,
},
},
required: ['firstName', 'lastName'],
};
const ajv = new Ajv({
allErrors: true,
useDefaults: true,
keywords: ['uniforms'],
});
function createValidator<T>(schema: JSONSchemaType<T>) {
const validator = ajv.compile(schema);
return (model: Record<string, unknown>) => {
validator(model);
return validator.errors?.length ? { details: validator.errors } : null;
};
}
const schemaValidator = createValidator(schema);
export const bridge = new JSONSchemaBridge({
schema,
validator: schemaValidator,
});
4. Finally, use it in a form!
uniforms theme packages provide the AutoForm
component, which is able to generate the form based on the given schema.
All we have to do now is to pass the previously created GuestSchema to the AutoForm
:
import React from 'react';
import { AutoForm } from 'uniforms-semantic';
import { bridge as schema } from './GuestSchema';
export function GuestFormBasic() {
return <AutoForm schema={schema} onSubmit={console.log} />;
}
And that's it! AutoForm
will generate a complete form with labeled fields, errors list (if any) and a submit button.
Also, it will take care of validation and handle model changes.