jupiteror
jupiteror

Reputation: 1205

Using react-input-mask with formik and formik-antd

I'm using formik with @jbuschke/formik-antd. I need to apply a mask +7 (___) ___-__-__ to an input, so I would like to use react-input-mask.

At the same time I need to parse the value and remove symbols except + and digits, so I handle onChange and setFieldValue myself. I can get changedValue in the console log, but on submit I'm getting the initial value, not the changed one.

Here is my code and the demo:

const CustomInput = props => (
  <InputMask {...props}>{inputProps => <Input {...inputProps} />}</InputMask>
);

const CloseForm = () => (
  <Formik
    initialValues={{ phone: "" }}
    onSubmit={(values, { setSubmitting }) => {
      setTimeout(() => {
        alert(JSON.stringify(values, null, 2));
        setSubmitting(false);
      }, 400);
    }}
    validate={handleValidate}
  >
    {({ isSubmitting, values, setFieldValue }) => {
      return (
        <Form>
          <FormItem name="phone" label="Phone" required="true">
            <CustomInput
              mask="+7 (999) 999-99-99"
              name="phone"
              onChange={e => {
                const value = e.target.value || "";
                const changedValue = value
                  .replace(/\)/g, "")
                  .replace(/\(/g, "")
                  .replace(/-/g, "")
                  .replace(/ /g, "");
                console.log({ value });
                console.log({ changedValue });
                setFieldValue("phone", value);
              }}
            />
          </FormItem>
          <SubmitButton type="primary" disabled={isSubmitting}>
            Submit
          </SubmitButton>
          <pre>{JSON.stringify(values, null, 2)}</pre>
        </Form>
      );
    }}
  </Formik>
);

How can it be fixed?

Upvotes: 3

Views: 14241

Answers (1)

Dennis Vash
Dennis Vash

Reputation: 53874

The problem is that you parsing the value but you don't update it anywhere, so changedValue dies at the end of the scope.

Move the parsing to onSubmit callback, not only you making unnecessary parsing on every render but also you won't be needed another state for the parsing value.

Hint: use a single regex expression, no need so many replaces.

const CloseForm = () => (
  <Formik
    initialValues={{ phone: '' }}
    onSubmit={(value, { setSubmitting }) => {
      const changedValue = value.phone
        .replace(/\)/g, '')
        .replace(/\(/g, '')
        .replace(/-/g, '')
        .replace(/ /g, '');

      setTimeout(() => {
        alert(JSON.stringify(changedValue, null, 2));
        setSubmitting(false);
      }, 400);
    }}
    validate={handleValidate}
  >
    {({ isSubmitting, values, setFieldValue }) => {
      return (
        <Form>
          <FormItem name="phone" label="Phone" required="true">
            <CustomInput
              mask="+7 (999) 999-99-99"
              name="phone"
              onChange={e => {
                const value = e.target.value || '';
                console.log({ value });
                setFieldValue('phone', value);
              }}
            />
          </FormItem>
          <SubmitButton type="primary" disabled={isSubmitting}>
            Submit
          </SubmitButton>
          <pre>{JSON.stringify(values, null, 2)}</pre>
        </Form>
      );
    }}
  </Formik>
);

Edit Q-57191028-FormikSubmit

Upvotes: 2

Related Questions