LayoutGridField
The LayoutGridField
will render a schema, uiSchema and formData combination out into a GridTemplate
in the shape
described in the uiSchema. To define the grid to use to render the elements within a field in the schema, provide in
the uiSchema for that field the object contained under a ui:layoutGrid
element. E.g. (as a JSON object):
{
"field1" : {
"ui:field": "LayoutGridField",
"ui:layoutGrid": {
"ui:row": { ... }
}
}
}
See the LayoutGridField usage for more detailed walk-through on how to use the component. This page is condensed
version of the uiSchema
APIs for faster reference.
ui:row
The outermost level of a LayoutGridField
is the ui:row
that defines the nested rows, columns, and/or condition
elements (i.e. "grid elements") in the grid. This definition is either a simple "grid elements" OR an object with
native GridTemplate
implementation-specific props and a children
array of "grid elements". E.g. (as JSON objects):
Simple ui:row
definition, without additional GridTemplate
props:
{
"ui:row": [
{ "ui:row"|"ui:col"|"ui:columns"|"ui:condition": ... },
...
]
}
Complex ui:row
definition, with additional GridTemplate
(this example uses @mui/material/Grid2
native props):
{
"ui:row": {
"spacing": 2,
"size": {
"md": 4
},
"alignContent": "flex-start",
"className": "GridRow",
"children": [
{
"ui:row"|"ui:col"|"ui:columns"|"ui:condition": ...
},
...
]
}
}
NOTE: Special note about the native
className
prop values. All className values will automatically be looked up in theformContext.lookupMap
in case they have been defined using a CSS-in-JS approach. In other words, from the example above, if theForm
was constructed with alayoutGridLookupMap
set to{ GridRow: cssInJs.GridRowClass }
then when rendered, the nativeGridTemplate
will get theclassName
with the value fromcssInJs.GridRowClass
. This automatic lookup will happen for any of the "grid elements" when rendering withGridTemplate
props. If multiple className values are present, for example:{ className: 'GridRow GridColumn' }
, the classNames are split apart, looked up individually, and joined together to form one className with the values fromcssInJs.GridRowClass
andcssInJs.GridColumnClass
. See the example in the usage documentation.
ui:col
The ui:col
grid element is used to specify the list of columns within a grid row. A ui:col
element can take on
several forms:
- a simple list of dotted-path field names within the root field;
- a list of objects containing the dotted-path field
name
any other props that are gathered intoui:options
for the field; - a list with a one-off
render
functional component with or without a non-fieldname
identifier and any other to-be-spread props; and - an object with native
GridTemplate
implementation specific props and achildren
array with 1) or 2) or even a nestedui:row
or aui:condition
containing aui:row
(although this should be used carefully). E.g. (as JSON objects):
Simple ui:col
definition, without additional GridTemplate
props and form 1 only children:
{
"ui:col": ["innerField", "inner.grandChild", ...]
}
Complicated ui:col
definition, without additional GridTemplate
props and form 2 only children:
{
"ui:col": [
{ "name": "innerField", "fullWidth": true },
{ "name": "inner.grandChild", "fullWidth": false },
...
]
}
More complicated ui:col
definition, without additional GridTemplate
props and form 2 children, one being a
one-off render
functional component without a non-field name
identifier
{
"ui:col": [
"innerField",
{
"render": "WizardNavButton",
"isNext": true,
"size": "large"
}
]
}
Most complicated ui:col
definition, additional GridTemplate
props and form 1, 2 and 3 children (this example
uses @mui/material/Grid2 native props):
{
"ui:col": {
"size": { "md": 4 },
"className": "GridColumn",
"children": [
"innerField",
{ "name": "inner.grandChild", "fullWidth": true },
{ "name": "customRender", "render": "CustomRender", "toSpread": "prop-value" },
{ "ui:row|ui:condition": ... },
...
]
}
}
NOTE: If a
name
prop does not exist or its value does not match any field in a schema, then it is assumed to be a customrender
component. If therender
prop does not exist, a null render will occur. Ifrender
is a string, its value will be looked up in theformContext.lookupMap
first before defaulting to a null render. If the resulting looked uprender
is not a function (React components are functions), then it will be a null render.
ui:columns
The ui:columns
grid element is syntactic sugar to specify a set of ui:col
columns that all share the same set of
native GridTemplate
props. In other words rather than writing the following configuration that renders a
<GridTemplate>
element with 3 <GridTemplate column className="GridColumn col-md-4">
nodes and 2
<GridTemplate column className="col-md-6">
nodes within it (one for each of the fields contained in the children
list):
{
"ui:row": {
"children": [
{
"ui:col": {
"className": "GridColumn col-md-4",
"children": ["innerField"]
}
},
{
"ui:col": {
"className": "GridColumn col-md-4",
"children": ["inner.grandChild"]
}
},
{
"ui:col": {
"className": "GridColumn col-md-4",
"children": [{ "name": "inner.grandChild2" }]
}
},
{
"ui:col": {
"className": "col-md-6",
"children": ["innerField2"]
}
},
{
"ui:col": {
"className": "col-md-6",
"children": ["inner.grandChild3"]
}
}
]
}
}
One can write this instead:
{
"ui:row": {
"children": [
{
"ui:columns": {
"className": "GridColumn col-md-4",
"children": ["innerField", "inner.grandChild", { "name": "inner.grandChild2", "fullWidth": true }]
}
},
{
"ui:columns": {
"className": "col-md-6",
"children": ["innerField2", "inner.grandChild3"]
}
}
]
}
}
NOTE: This syntax differs from
"ui:col": { "className": "col-md-6", "children": ["innerField2", "inner.grandChild3"] }
in that theui:col
will render the two children fields inside a single<GridTemplate "className": "col-md-6",>
element.
ui:condition
The final grid element, ui:condition
, allows for conditionally displaying "grid elements" within a row based on the
current value of a field as it relates to a (list of) hard-coded value(s). There are four elements that make up a
ui:condition
:
- the dotted-path
field
name within the root field that makes up the left-side of the condition; - the hard-coded
value
(single or list) that makes up the right-side of the condition; - the
operator
that controls how the left and right sides of the condition are compared; and - the
children
array that defines the "grid elements" to display if the condition passes.
A ui:condition
uses one of three operators
when deciding if a condition passes:
- The
all
operator will pass when the right-side and left-side contains all the same value(s); - the
some
operator will pass when the right-side and left-side contain as least one value in common; - the
none
operator will pass when the right-side and left-side do not contain any values in common. E.g. (as JSON objects):
Here is how to render an if-then-else for field2
which is an enum that has 3 known values and supports allowing
any other value:
{
"ui:row": [
{
"ui:condition": {
"field": "field2",
"operator": "all",
"value": "value1",
"children": [
{ "ui:row": [...] }
],
}
},
{
"ui:condition": {
"field": "field2",
"operator": "some",
"value": ["value2", "value3"],
"children": [
{ "ui:row": [...] }
],
}
},
{
"ui:condition": {
"field": "field2",
"operator": "none",
"value": ["value1", "value2", "value3"],
"children": [
{ "ui:row": [...] }
]
}
}
]
}