Home > Software design >  Formik - Select first option in dropdown list when component gets loaded
Formik - Select first option in dropdown list when component gets loaded

Time:03-12

I have the following code which has a dropdown list with few values.

I want that when the component gets loaded, it selects the first option and let me submit right after.

I tried with the line below but no luck:

formik.setFieldValue(name, value);

Here you have the code:

import { ErrorMessage, Field, Form, Formik } from 'formik';
import { get } from 'lodash-es';
import React, { useEffect } from 'react';
import * as Yup from 'yup';

const DropdownListInput = ({ formik, name, value, children, handleChange }) => {

  useEffect(() => {
    const firstOptionValue = get(children, '[0].props.value', '');
    console.log({firstOptionValue});
    if (value === '' && firstOptionValue !== '') {
      formik.setFieldValue(name, firstOptionValue);
    }
  }, []);

  return (
    <select value={value} onChange={(e) => handleChange(e.target.value)}>
      {
        children.map(({props: {value, children: text}}, index) =>
          <option value={value} key={index}>{text}</option>
        )
      }
    </select>
  );
}

export default () => {
  return (
    <Formik
      initialValues={{
        email: '',
      }}
      validationSchema={Yup.object().shape({
        email: Yup.string()
          .required('Email is required.')
          .email('Email is invalid.'),
      })}
      onSubmit={(values, { setSubmitting }) => {
        console.log(values);
        setSubmitting(false);
      }}
      enableReinitialize
      validateOnMount
    >
      {(formik) => {
        return (
          <Form>
            <div>
              <Field
                component={DropdownListInput}
                formik={formik}
                name="email"
                value={formik.values.email}
                handleChange={(value) => {
                  console.log(value);
                  formik.setFieldValue('email', value);
                }}
              >
                <option value="[email protected]">Bill Bates</option>
                <option value="[email protected]">Steve Jobs</option>
                <option value="[email protected]">Elon Musk</option>
              </Field>
              <ErrorMessage name="email">
                {(error) => <div style={{ color: '#f00' }}>{error}</div>}
              </ErrorMessage>
            </div>
            <input type="submit" value="Submit" disabled={!formik.isValid} />
          </Form>
        );
      }}
    </Formik>
  );
};

Here you have the Stackblitz you can play with:

https://stackblitz.com/edit/react-formik-yup-example-uhdg-dt6cgk

Is there any way to select the first option automatically when the component gets loaded?

Requirements:

  • I need the Submit button to be enabled automatically.
  • Using initialValues is not an option for me because the dropdown is in the middle of a more complex context then it is the same dropdown who has to trigger the setting of that value.

If you want you can post your forked Stackblitz.

Thanks!

CodePudding user response:

You should be able to just add the initial value as the default value. Since that would be selected by default, the initial value can reflect the same, and be changed on change.

initialValues={{
    email: '[email protected]',
  }}

CodePudding user response:

This requirement is very straightforward where you always want to have a selected option in your dropdown, defaulting to the first one. To do that you have to set select attribute of tag just for first one. It's a pure HTML thing.

you can find the reference here:

 <option value="[email protected]" select>
   Bill Bates
 </option>

https://stackblitz.com/edit/react-formik-yup-example-uhdg-bgzdh7?file=Registration.js

Another scenario would be you want to preserve the user selection on rerenders, to do that you can rely on setting up initialValues to what user has selected.

In that way, if any selection is there reflect that or else default to the very first item of the dropdown.

  • Related