Skip to content

Commit 499f6a2

Browse files
authored
Merge pull request #447 from data-driven-forms/form-level-error-template
Added example of form level validation errors.
2 parents f2d80c3 + 03e7c43 commit 499f6a2

File tree

3 files changed

+148
-1
lines changed

3 files changed

+148
-1
lines changed
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
/* eslint-disable react/prop-types */
2+
import React from 'react';
3+
import FormRenderer from '@data-driven-forms/react-form-renderer/dist/cjs/form-renderer';
4+
import componentTypes from '@data-driven-forms/react-form-renderer/dist/cjs/component-types';
5+
import validatorTypes from '@data-driven-forms/react-form-renderer/dist/cjs/validator-types';
6+
import useFormApi from '@data-driven-forms/react-form-renderer/dist/cjs/use-form-api';
7+
import FormSpy from '@data-driven-forms/react-form-renderer/dist/cjs/form-spy';
8+
import TextField from '@data-driven-forms/mui-component-mapper/dist/cjs/text-field';
9+
import Button from '@material-ui/core/Button';
10+
import Grid from '@material-ui/core/Grid';
11+
import Typography from '@material-ui/core/Typography';
12+
import List from '@material-ui/core/List';
13+
import ListItem from '@material-ui/core/ListItem';
14+
import ListItemText from '@material-ui/core/ListItemText';
15+
import { makeStyles } from '@material-ui/styles';
16+
import red from '@material-ui/core/colors/red';
17+
18+
const componentMapper = {
19+
[componentTypes.TEXT_FIELD]: TextField
20+
};
21+
22+
const schema = {
23+
title: 'List of errors on the top if the form',
24+
fields: [
25+
{
26+
component: componentTypes.TEXT_FIELD,
27+
name: 'name',
28+
label: 'Name',
29+
isRequired: true,
30+
validate: [
31+
{
32+
type: validatorTypes.REQUIRED
33+
}
34+
]
35+
},
36+
{
37+
component: componentTypes.TEXT_FIELD,
38+
name: 'age',
39+
label: 'Age',
40+
type: 'number',
41+
isRequired: true,
42+
validate: [
43+
{
44+
type: validatorTypes.REQUIRED
45+
}
46+
]
47+
}
48+
]
49+
};
50+
51+
const useFormErrorsStyle = makeStyles(() => ({
52+
listError: {
53+
color: red[500] // you can use your theme color if you have theme provider
54+
}
55+
}));
56+
57+
const FormErrors = () => {
58+
const classes = useFormErrorsStyle();
59+
return (
60+
<FormSpy>
61+
{({ errors }) => (
62+
<List>
63+
{Object.entries(errors).map(([key, error]) =>
64+
error ? (
65+
<ListItem button component="li" key={key}>
66+
<ListItemText className={classes.listError}>
67+
{key}: {error}
68+
</ListItemText>
69+
</ListItem>
70+
) : null
71+
)}
72+
</List>
73+
)}
74+
</FormSpy>
75+
);
76+
};
77+
78+
const FormTemplate = ({ formFields, schema }) => {
79+
const { handleSubmit, onReset, onCancel, getState } = useFormApi();
80+
const { submitting, pristine } = getState();
81+
82+
return (
83+
<Grid item xs={12}>
84+
<form onSubmit={handleSubmit}>
85+
<Grid container item spacing={2}>
86+
<Grid item xs={12}>
87+
<Typography variant="h4" component="h2">
88+
{schema.title}
89+
</Typography>
90+
</Grid>
91+
<Grid item xs={12}>
92+
<FormErrors />
93+
</Grid>
94+
<Grid container item xs={12} spacing={4}>
95+
{formFields}
96+
</Grid>
97+
<Grid item xs={12}>
98+
<FormSpy>
99+
{() => (
100+
<div>
101+
<Button disabled={submitting} style={{ marginRight: 8 }} type="submit" color="primary" variant="contained">
102+
Submit
103+
</Button>
104+
<Button disabled={pristine} style={{ marginRight: 8 }} onClick={onReset} variant="contained">
105+
Reset
106+
</Button>
107+
<Button variant="contained" onClick={onCancel}>
108+
Cancel
109+
</Button>
110+
</div>
111+
)}
112+
</FormSpy>
113+
</Grid>
114+
</Grid>
115+
</form>
116+
</Grid>
117+
);
118+
};
119+
120+
const asyncSubmit = (values, api) =>
121+
new Promise((resolve) =>
122+
setTimeout(() => {
123+
console.log('FormValues', values);
124+
resolve('Yay');
125+
}, 1500)
126+
);
127+
128+
const FormLevelErrors = () => (
129+
<Grid container spacing={4}>
130+
<FormRenderer
131+
FormTemplate={FormTemplate}
132+
componentMapper={componentMapper}
133+
schema={schema}
134+
onSubmit={asyncSubmit}
135+
onCancel={() => console.log('Cancelling')}
136+
onReset={() => console.log('Resetting')}
137+
/>
138+
</Grid>
139+
);
140+
141+
export default FormLevelErrors;

packages/react-renderer-demo/src/app/pages/renderer/form-template.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,13 @@ With using `useFormApi` hook you can get access to all form information and func
3737

3838
You can customize form buttons in your [FormTemplate](/renderer/renderer-api#requiredprops) component
3939

40-
<CodeExample source="components/custom-buttons" mode="preview" />
40+
<CodeExample source="components/form-template/custom-buttons" mode="preview" />
41+
42+
## Form level validation
43+
44+
To display all form errors, you will need to add a component to your FormTemplate. Following example shows how to list all errors at the top of a form.
45+
46+
<CodeExample source="components/form-template/form-level-validation" mode="preview" mapper="mui" />
4147

4248
## Default FormTemplates
4349

0 commit comments

Comments
 (0)