How to apply Formik with Chakra in typescript? - reactjs

I am trying to use following example on Chakra but using Typescript
<Formik
initialValues={{ name: "Sasuke" }}
onSubmit={(values, actions) => {
setTimeout(() => {
alert(JSON.stringify(values, null, 2));
actions.setSubmitting(false);
}, 1000);
}}
>
{(props) => (
<Form>
<Field name="name" validate={validateName}>
{/* Trouble in this line below*/}
{({ field, form }) => (
<FormControl
isInvalid={form.errors.name && form.touched.name}
>
<FormLabel htmlFor="name">First name</FormLabel>
<Input {...field} id="name" placeholder="name" />
<FormErrorMessage>
{form.errors.name}
</FormErrorMessage>
</FormControl>
)}
</Field>
<Button
mt={4}
colorScheme="teal"
isLoading={props.isSubmitting}
type="submit"
>
Submit
</Button>
</Form>
)}
</Formik>
How do I define "field" and "form" in Typescript ? is there a prop for that ? or should I just define those things in an interface ?

I was encountering the same problem and gave a look at the source code.
You should be able to use FieldInputProps<T> where T is the value type you expect and FormikProps<T> where T is the type definition of the values you expect.
E.g.
{({ field, form }: { field: FieldInputProps<string>, form: FormikProps<{ name: string, surname: string }> }) => {
...
}}

Related

Form not Submitting in React using Formik and Yup

I'm using Autocomplete component in Material UI and I'm using Formik and Yup for validations.
My problem is that when I submit my values and console it. It doesn't appear which means it doesn't conform to its yup validation.
Pls check my codesandbox here
Click here
<Formik
validationSchema={citySchema}
initialValues={{ city_id: [{ id: null, name: "" }] }}
onSubmit={submit}
>
{({ handleChange, values, setFieldValue, touched, errors }) => (
<Form>
<Autocomplete
id="city_id"
name="city_id"
options={cities}
getOptionLabel={(option) => option.name}
style={{ width: 300 }}
onChange={(e, value) => {
setFieldValue("city_id", value);
}}
renderInput={(params) => (
<TextField
label="City"
variant="outlined"
helperText={touched.city_id && errors.city_id}
error={touched.city_id && Boolean(errors.city_id)}
{...params}
/>
)}
/>
<Button variant="contained" color="primary" type="submit">
Submit
</Button>
</Form>
)}
</Formik>
Your validationSchema requires a name but your code never supplies it.
Either make it optional or add a name input field.
An easy way to debug this is to print out the errors formik is supplying you:
<Form>
<pre>{JSON.stringify(errors, null, 2)}</pre>
<Autocomplete
...

Ant design <Form.List> create static array of forms

I am using antd with react to develop an application.
<Form.List name="secondaryContacts">
{(fields, { add, remove }) => {
return (
<div>
{fields.map((field, index) => (
<Form.Item
{...formItemLayoutWithOutLabel}
label={index === 0 ? "" : ""}
required={false}
key={field.key}
>
<Form.Item
{...field}
validateTrigger={["onChange", "onBlur"]}
rules={[
{
required: true,
validator: phoneNumberValidator
}
]}
>
<Input
placeholder="Secondary Contact"
addonAfter={
fields.length >= 1 ? (
<MinusCircleOutlined
onClick={() => {
remove(field.name);
}}
/>
) : null
}
/>
</Form.Item>
</Form.Item>
))}
<Form.Item {...formItemLayoutWithOutLabel}>
<Button
type="dashed"
onClick={() => {
add();
}}
style={{ width: "100%" }}
>
<PlusOutlined /> Add Secondary Contact
</Button>
</Form.Item>
</div>
);
}}
</Form.List>;
Above is the code I am using to add dynamic form fields with validation using Form.List.
Now I have a specific scenario where I need to show 7 Sliders(https://ant.design/components/slider/) for the selected time slot and store them in an array, so I thought of using Form.List and keep all sliders inside just like above(except that it's static).
But I am not clear how I can achieve it with Form.List and there are very few examples on the internet.
I have a scenario where I need to have an array of forms and club them as an array using Form.List.
You can use the initialValue property to set the static data
Example:
const staticValue = [{ formItem1: 'value1', formItem2: 'value2'}];
<Form.List name="formListName" initialValue={staticValue}>
{(fields, { add, remove }, { errors }) => (
fields.map((field) => (
<>
<Form.Item {...field} name={[field.name, 'formItem1']}>
<Input placeholder="Field 1" />
</Form.Item>
...
You still need <Form> component
Try
<Form>
<Form.List>
</Form.List>
</Form>

Formik Validation of semantic-ui-react select-field(dropdown)

Hi guys i would like to validate semantic-ui form with a selectInput (dropdown) but it brings a warning and it does not work. Here is the warning:
Formik called handleChange, but you forgot to pass an "id" or "name" attribute to your input:
<div role="option" aria-checked="false" aria-selected="false" class="item" style="pointer-events: all;"><span class="text">value Two</span></div>Formik cannot determine which value to update.
Formik validates the textInput properly but for the selectInput it brings the above warning and nothing is taken in the handleSubmit function.
Below is the snip of the code please.
<Formik
initialValues={{ levelValue: "", attachLevel: "" }}
validationSchema={Yup.object({
levelValue: Yup.string().required("Required Please"),
attachLevel: Yup.string().required("Required Please")
})}
onSubmit={(values, { setSubmitting }) => {
setTimeout(() => {
alert(JSON.stringify(values, null, 2));
setSubmitting(false);
}, 400);
}}
>
{({
values,
errors,
touched,
handleChange,
handleBlur,
handleSubmit,
isSubmitting
}) => (
<Form onSubmit={handleSubmit}>
<Form.Group>
<Form.Input
name="levelValue"
placeholder="Define Level..."
onChange={handleChange}
onBlur={handleBlur}
value={values.levelValue}
type="text"
/>
{touched.levelValue && errors.levelValue ? (
<span className="span_error">
{errors.levelValue}
</span>
) : null}
</Form.Group>
<Form.Group>
<Form.Input
control={Select}
name="attachLevel"
onChange={handleChange}
onBlur={handleBlur}
defaultValue={values.attachLevel}
multiple
options={Class}
/>
{touched.attachLevel && errors.attachLevel ? (
<span className="span_error">
{errors.attachLevel}
</span>
) : null}
</Form.Group>
<Button
color="blue"
type="submit"
className="submit"
disabled={isSubmitting}
>
<Icon name="add" />
Attach
</Button>
</Form>
)}
</Formik>
Any Help will be appreciable please....

formik fields are not getting value

I'm using Formik in my React and redux project, but Formik fields are not getting value and onChange field function not working!
this form is for editing a customer. I'm using Formik in another part of project and i don't have a problem. I don't know what to do?
<Formik
initialValues={props.selectedCustomer.id ? props.selectedCustomer : emptyCustomer}
validationSchema={customerValidationSchema}
onSubmit={async (values: ICustomer, actions: FormikActions<any>) => {
console.log(values)
try {
await postCustomer(values)
props.selectedCustomer.id ? enqueueSnackbar('success') : enqueueSnackbar('fail')
actions.resetForm()
getCustomers(pageNum, pageSize)
setAddDialog(false)
}
catch (error) {
enqueueSnackbar(error, { variant: 'default' })
}
}}
>
{() => (
<Form id="addCustomerForm">
<div id="addCustomerDiv" className={clsx({
[classes.noDisplay]: !addDialog
})}>
<Grid style={{marginRight: '0.5rem'}} container spacing={5}>
<Grid item xs={2}>
<Field
name="firstName"
render={({ field, form }: FieldProps<ICustomer>) => (
<TextField
margin="dense"
id="firstName"
label="firstName"
fullWidth
{...field}
error={form.errors.firstName && form.touched.firstName ? true : false}
/>
)}
/>
</Grid>
<Button
type='submit'
form="addCustomerForm"
color="primary"
variant="contained"
style={{marginTop: '3rem'}}
className={clsx({
[classes.noDisplay]: !addDialog
})}
>
submit
</Button>
</Grid>
</Grid>
</div>
</Form>
)}
</Formik>
what is the problem?
I added enableReinitialize in Formik component and it worked.

How to reset / empty form after submit in Formik

So I've got my form. And I simply want it to be empty after the submit is successfull.
I've seen that I should be using enableReinitializing and change the value manually like : this.values.content = "".
But I'm not managing to understand where can I put this option?
<Formik
enableReinitializing //This is not working
initialValues={{
content: "",
}}
validationSchema={validAddMessageToProjectSchema(
this.props.intl.locale
)}
validateOnBlur={true}
onSubmit={ async ( values: AddMessageToProjectFormValue,
{ setSubmitting }: any
) => { await mutate({ variables: values });
setSubmitting(false);
}}
>
{({ isSubmitting, values, errors, touched, setFieldValue }) => {
return (
<Form className="addMessageToProject-form">
<div>
<FormattedMessage
id="addMessageToProject.descriptionField"
defaultMessage="Describe your post"
>
{msg => (
<Field
name="content"
placeholder={msg}
component={
TextAreaField
}
/>
)}
</FormattedMessage>
</div>
<Button
type="primary"
htmlType="submit"
className="addMessageToProject-form__submit form-submit"
disabled={isSubmitting}
>
<FormattedMessage
id="addMessageToProject.button"
defaultMessage="Send Message"
/>
</Button>
</Form>
);
}}
</Formik>
You can do it like this in onSubmit callback
onSubmit={(values, {setSubmitting, resetForm}) => {
handleSave(params, () => {
resetForm(initialValues)
})
setSubmitting(false);
}}
And this is not enableReinitializing instead use enableReinitialize

Resources