How to make Formik detect when Checkbox field is checked?

13,346

Solution 1

You assign different name to Checkbox component:

Instead of:

 <Field
   type="checkbox"
   name='check'
   id='check'
   label='Check the mark'
   component={Checkbox}
/>

Use:

 <Field
   type="checkbox"
   name='checkbox'
   id='check'
   label='Check the mark'
   component={Checkbox}
/>

Check if your Checkbox works now.

And don't forget to check if your checkbox is changing value, I think you should implement setFieldValue inside Checkbox component to send new value to formik.

You can access to setFieldValue in Checkbox`s props.

Final code Checkbox will be:

//You need to include form and name in props.
export const Checkbox = ({ form, name, label, disabled, id, className }: Props) => {
  return (
    <FormGroup>
      // You need to include onChange
      <input type="checkbox" id={name} name={name} onChange={(e) => {form.setFieldValue(name,e.target.checked)}}/>
      <label htmlFor={name}> {label}</label>
      <ErrorMessage component="div" className="input-error" name="checkbox" />
    </FormGroup>
  );
};

Solution 2

To complement Adrian Naranjo's answer, you are implementing Formik's "onChange" callback on the checkbox.

<Formik
 initialValues={{ ... }}
 validationSchema={Schema}
 onSubmit={(values) => { ... }}
>
{
  ({ handleChange, ...rest } => {

You need to pass this handleChange to your Checkbox component.

Formik's Field component will make an onChange callback available then you can pass it to the <input type="checkbox" />.

https://jaredpalmer.com/formik/docs/api/field

Share:
13,346
dawn
Author by

dawn

Safety in solitude. I like to create.

Updated on July 25, 2022

Comments

  • dawn
    dawn almost 2 years

    I'm making a Checkbox component which needs validation (done with Yup). But it doesn't retrieves the actual value from the checbox, just from the one inside initialValues.

    Code of the form:

        <div className='metro custom-pg'>
          <ThemeContext.Provider theme={theme}>
            <Formik
              initialValues={{
                text: '',
                email: '',
                phone: '',
                select: '',
                multi: [],
                checkbox: false,
              }}
              validationSchema={Schema}
              onSubmit={(values) => {
                alert(JSON.stringify(values, null, 2));
                console.log("values", values);
              }}
            >
              {({
                errors,
                values,
                touched,
                handleSubmit,
                setFieldValue,
                setFieldTouched,
              }) => (
                <Form onSubmit={handleSubmit}>
                  <Field
                    id='text-field'
                    label='Plain text'
                    name='text'
                    type='text'
                    placeholder='Enter some characters'
                    component={TextField}
                  />
                  <Field
                    id='email-field'
                    label='Email'
                    name='email'
                    type='email'
                    placeholder='Enter your email'
                    component={TextField}
                  />
                  <Field
                    id='phone-email'
                    label='Phone'
                    name='phone'
                    type='phone'
                    placeholder='Enter your phone'
                    component={TextField}
                  />
                  <Field
                    id='select'
                    name='select'
                    name='select'
                    label='Select an option'
                    options={options}
                    component={Select}
                  />
                  <MultiSelect
                    id='multiselect'
                    name='multi'
                    label='Select multiple options'
                    options={multiOptions}
                    value={values.multi}
                    onChange={setFieldValue}
                    onBlur={setFieldTouched}
                    touched={touched.multi}
                    error={errors.multi}
                  />
                  <Field
                    type="checkbox"
                    name='check'
                    id='check'
                    label='Check the mark'
                    component={Checkbox}
                  />
                  <Button variant="primary" type="submit">Submit</Button>
                  </Form>
              )}
            </Formik>
          </ThemeContext.Provider>
        </div>
    

    Code of Checkbox:

    // @flow
    import * as React from "react";
    import { Field, ErrorMessage } from 'formik';
    import { FormGroup, FormLabel } from "react-bootstrap";
    
    export type Props = {
      label?: String,
      id?: String,
      name?: String,
      disabled?: boolean,
      onChange: function,
      className?: string
    };
    
    export const Checkbox = ({ label, disabled, id, className }: Props) => {
      return (
        <FormGroup>
          <input type="checkbox" id={name} name={name} />
          <label htmlFor={name}> {label}</label>
          <ErrorMessage component="div" className="input-error" name="checkbox" />
        </FormGroup>
      );
    };
    
    Checkbox.defaultProps = {
      label: 'Default text',
      name: 'checkbox',
      disabled: false,
      className: ''
    
    }
    
    export default Checkbox;