Skip to content

Instantly share code, notes, and snippets.

@ilhamsa1
Created February 19, 2020 05:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ilhamsa1/6544e1d0c4e3967706725be28fe35e48 to your computer and use it in GitHub Desktop.
Save ilhamsa1/6544e1d0c4e3967706725be28fe35e48 to your computer and use it in GitHub Desktop.
example form repeater with fieldarray in formik
/* eslint-disable react/jsx-indent */
import React from 'react'
import { observer, inject } from 'mobx-react'
import { TextField, Icon, Button } from 'site_library/components'
import FormHelperText from '@material-ui/core/FormHelperText'
import { Formik, FieldArray, Form } from 'formik'
import validate from './validate'
const FormRepeater = () => {
const errorMessage = (errors, index, field) => {
return errors && errors.friends && errors.friends.length > 0 && errors.friends[index] && errors.friends[index][field]
}
const isError = (errors, touched, index, field) => {
return errors && errors.friends && errors.friends.length > 0 && errors.friends[index] && errors.friends[index][field] &&
touched && touched.friends && touched.friends.length > 0 && touched.friends[index] && touched.friends[index][field]
}
const mainFormError = (errors) => {
return errors && errors.friends && typeof errors.friends !== 'object' && errors.friends
}
const formRepeater = () => {
return (
<Formik
validationSchema={validate}
initialValues={{ friends: [] }}
onSubmit={values => setTimeout(() => {
// handle action
alert(JSON.stringify(values, null, 2))
}, 500)}
render={({ values, errors, handleChange, touched }) => (
<Form>
<FieldArray
name="friends"
render={arrayHelpers => (
<div>
<div style={{ margin: '1rem' }}>
<Icon
fixedSize={false}
color="blue"
dark
onClick={() => {
arrayHelpers.push({
firstName: '',
lastName: '',
email: '',
})
}}
name="add"
size={20}
/>
</div>
{
values.friends && values.friends.length > 0 && (
values.friends.map((item, index) => (
<div key={item.name} style={{ display: 'flex' }}>
<div style={{ margin: '1rem' }}>
<Icon
color="primary"
onClick={() => {
console.log('ss')
}}
name="dehaze"
size={24}
/>
</div>
<div style={{ margin: '1rem' }}>
<TextField
type="text"
label="FIRST NAME"
placeholder="First Name"
value={item.firstName}
name={`friends.${index}.firstName`}
onChange={handleChange}
error={isError(errors, touched, index, 'firstName')}
errorMessage={errorMessage(errors, index, 'firstName')}
/>
</div>
<div style={{ margin: '1rem' }}>
<TextField
type="text"
label="LAST NAME"
value={item.lastName}
placeholder="Last Name"
name={`friends.${index}.lastName`}
onChange={handleChange}
error={isError(errors, touched, index, 'lastName')}
errorMessage={errorMessage(errors, index, 'lastName')}
/>
</div>
<div style={{ margin: '1rem' }}>
<TextField
type="text"
label="EMAIL"
value={item.email}
placeholder="Email"
name={`friends.${index}.email`}
onChange={handleChange}
error={isError(errors, touched, index, 'email')}
errorMessage={errorMessage(errors, index, 'email')}
/>
</div>
<div style={{ margin: '1rem' }}>
<Icon
color="primary"
dark
fixedSize={false}
onClick={() => {
arrayHelpers.remove(index)
}}
name="close"
size={20}
/>
</div>
</div>
))
)
}
<FormHelperText
error={!!errors}
>
{mainFormError(errors)}
</FormHelperText>
{
values.friends.length !== 0 && (
<Button type="submit">
Submit
</Button>
)
}
</div>
)}
/>
</Form>
)}
/>
)
}
return (
<div>
{formRepeater()}
</div>
)
}
export default inject(
'routing',
)(
observer(FormRepeater),
)
import * as Yup from 'yup'
const validateSchema = Yup.object().shape({
friends: Yup.array()
.of(
Yup.object().shape({
firstName: Yup.string()
.min(4, 'too short')
.required('This field is required'),
lastName: Yup.string()
.min(3, 'cmon')
.required('This field is required'),
email: Yup.string()
.email('Please enter valid mail')
.required('This field is required'),
}),
)
.required('Must have friends') // these constraints are shown if and only if inner constraints are satisfied
.min(3, 'Minimum of 3 friends'),
})
export default validateSchema
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment