Create complex forms via JSON using your design system and/or UI library
Design Systems and UI libraries include form components, so why should you spend time jamming them in as "custom fields" or styling built in fields? Our philosophy is simple: generate forms via a JSON schema that seamlessly integrates the form components of your choosing and intuitively reflects props objects for those components.
The JSON Schema specification is very powerful and meant to be universal across language implementations - which is great but not always for forms. In React, the spec becomes increasingly difficult to read at a human level as a form scales, and the separation of UI vs Form schema directly contradicts the props pattern for React components.
npm install --save json-formik-formsimport React, { Component } from 'react'
import MyComponent from 'json-formik-forms'
import 'json-formik-forms/dist/index.css'
class Example extends Component {
render() {
return <MyComponent />
}
}- Schema
- Branching
- Conditional Fields
- Content & Custom Fields
- Dynamic Checkbox/Radio/Select Choices
- Repeatable Fields & Field Sets
The Form component provides a simple standardized way to create single and
multi-page web forms using only a JSON schema.
Form pages consist of an id, title (optional), description (optional),
and an array of field objects.
Fields use the field components in this design system and are declared via the
type key in each field object. Fields support all props listed within that
component's documentation - including required props. The following fields
are currently supported:
contentcustomcheckboxradiorepeatableselecttext- All other valid HTML input types will be rendered by the Field component.
The Form component supports logic for navigating to specific form pages;
including conditional navigation based on form field answers. By default, the
form will navigate sequentially through the pages array. Branching is defined
by adding the optional action object to a page object.
pages: [
{
id: 'page_1',
action: {
type: 'goto',
pageId: 'another_page_id' || (values) => {
if(values.field_1 === 'A') {
return 'page_3'
} else {
return 'page_2'
}
},
buttonText: 'Custom continue button text'
}
}
]
type: options aregoto** andnext**(default). -goto* requires the*page_id** to be defined -next* is set as the default for sequential page direction.pageId: accepts either astring** orfunction**.- The string must be a valid page object id in the form schema, invalid Ids will throw an error.
- The function receives a form values object as its sole parameter and expects a string (page_id) to be returned. It should be used to resolve conditional branching logic based on the page field values.
buttonText: optional string for custom text applied to the "continue" or "submit" button
The Form component provides a simple way to define additional fields that
will be conditionally displayed based on user selected values.
For example: a radio field has a choice of Other, and when the user selects
Other a new text field is displayed for the user to enter the custom value.
Negative conditions (not) are supported where a field should not be displayed if the parent
value matches the designated value(s). Negation supercedes value conditions such that a field
will not be displayed if the parent value matches both a value and not condition.
value = 'any' is supported where you want to display a conditional field once the parent field
has any valid field value (i.e. not an empty string or array.)
Each field defined in the JSON fields array has an optional attribute named
conditionals. It has three attributes:
- fields: array of field objects to display for the condition.
- not: string or array of strings
- value: string or array of strings
type: 'radio',
choices: [
{ label: 'A', value: 'A' },
{ label: 'B', value: 'B' },
{ label: 'C', value: 'C' },
{ label: 'Other', value: 'Other' }
],
name: 'select_1',
conditionals: [
{
value: 'Other',
not: 'C',
fields: [
{
type: 'text',
label: 'Enter other value',
name: 'select_1_other'
}
]
}
The Form component supports content and custom field types which accept a
Component function to be rendered. They are provided the all formik props and actions, in
addition to internal form values.
Content fields are removed from the form value set and automatic review page. Use the custom
field type for custom input components.
goBackToPage- function to return to a form page in the pageHistory. -parameter*: integerpageHistory- array of page indexes (integers) that have been visited in the form.pages- array of page objects provided in the form schema.- https://jaredpalmer.com/formik/docs/api/formik
Checkbox, Radio, and Select field types allow for their choice options to dynamically update based on the string value of a single parent field. Dynamic choice options are defined by two objects. The first object accepts two parameters:
- parentField:
string - choices:
object
The second, nested choices object is a key/value pair:
- key:
stringvalue which matches parent field value - value:
arrayof choice objects to display
{
type: 'select',
name: 'dynamic_choice_field',
choices: {
parentField: 'sample_parent_field',
choices: {
orange: [
{ label: 'Tangerine', value: 'tangerine'},
{ label: 'Clementine', value: 'clementine' },
{ label: 'Navel', value: 'navel' }
],
apple: [
{ label: 'Honeycrisp', value: 'honeycrisp' },
{ label: 'McIntosh', value: 'mcintosh' },
{ label: 'Ambrosia', value: 'ambrosia' },
{ label: 'Empire', checked: true, value: 'empire' },
{ label: 'Granny Smith', value: 'granny_smith' }
],
lemon: [
{ label: 'Meyer', checked: true, value: 'meyer' },
{ label: 'Ponderosa', value: 'ponderosa' }
]
}
}
}
The Form component supports a repeatable field type which accepts and array of field objects
to define a field group. This helps the user with common array/list manipulations, such as "add
another address or person".
The field returns an array of key/value objects for each field group the user adds.
fields- array of field objectslabel- stringname- string
addButton- props object to customize the add button. Supports atextproperty to replace the default+and all other props will be passed to theButtoncomponentclassName- Additional classes to be added to the rootdivelementdeleteButton- props object to customize the delete button for all field groups. Supports atextproperty to replace the default-and all other props will be passed to theButtoncomponenthint- Additional hint text to displaylabelClassName- Additional classes to be added to the labelmax- maximum number of field groups allowedrequirementLabel- Text showing the requirement ("Required", "Optional", etc.).
{
type: 'repeatable',
label: 'This is a repeatable set of fields',
name: 'repeat_all_the_fields',
fields: [
{
type: 'text',
name: 'repeat_input',
label: 'Repeat Input'
}
]
}
MIT © 5arias