4

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?

1 Answer 1

2

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

Sign up to request clarification or add additional context in comments.

9 Comments

Thank you very much! I replaced regex expression with const changedValue = value.phone.replace(/\(|\)|\s|\-/g, "");. But I have a question, how can I do this with multiple inputs, where phone is just one of the values? How could onSubmit look like in this case?
This question out of scope, I suggest asking another one
Originally I had alert(JSON.stringify(values, null, 2));, which was supposed to pass all values. And in your answer it is alert(JSON.stringify(changedValue, null, 2));, which passes only one changed value. That' s why I'm asking.
values is an object... so use its values as you like, in the answer its values.phone, in your case pass values.somethingElse and so on
Does you answer update values.phone inside values? As I understand, values stay untouched, and I can get only a new variable changedValue additionally. My intention was to change values.phone inside values with something like setFieldValue.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.