How to process onChange and change focus to new <Field>?

Viewed 8575

I'm using Formik (with withFormik()) and want to check a <Field> as a user types in it - after it has 4 characters in it, I want to focus on the next field so they can keep typing without having to move to the next field.

So my InnerForm has:

<Field
  type="text"
  name="credit1"
  inputmode="numeric"
  maxlength="4" />
<Field
  type="text"
  name="credit2"
  inputmode="numeric"
  maxlength="4" />

And my FormikInnerFormContainer = withFormik(...) has a validationSchema.

How could I catch changes on the first field, and move focus to the 2nd field if the first has 4 characters in?

I tried to override the onChange, but couldn't figure out how to update the Field contents with each character the user types.

2 Answers

You might use like this in Formik.

  focusChange(e) {
    if (e.target.value.length >= e.target.getAttribute("maxlength")) {
      e.target.nextElementSibling.focus();
    }
    ...

//Example implementation
import React from "react";
import { Formik } from "formik";

export default class Basic extends React.Component {
  constructor(props) {
    super(props);
    this.inputRef = React.createRef();
    this.focusChange = this.focusChange.bind(this);
  }

  focusChange(e) {
    if (e.target.value.length >= e.target.getAttribute("maxlength")) {
      e.target.nextElementSibling.focus();
    }
  }

  render() {
    return (
      <div>
        <h1>My Form</h1>
        <Formik
          initialValues={{ name: "" }}
          onSubmit={(values, actions) => {
            setTimeout(() => {
              alert(JSON.stringify(values, null, 2));
              actions.setSubmitting(false);
            }, 1000);
          }}
          render={props => (
            <form onSubmit={props.handleSubmit} ref={this.inputRef}>
              <input
                type="text"
                onChange={props.handleChange}
                onBlur={props.handleBlur}
                value={props.values.name}
                name="name"
                maxlength="4"
                onInput={e => this.focusChange(e)}
              />
              <input
                type="text"
                onChange={props.handleChange}
                onBlur={props.handleBlur}
                value={props.values.lastName}
                name="lastName"
                maxlength="4"
                onInput={this.focusChange}
              />
              <button type="submit">Submit</button>
            </form>
          )}
        />
      </div>
    );
  }
}

In vanilla javascript you can do this:

document.querySelectorAll('input').forEach(function(input) {
  input.addEventListener('keyup', function() {
    if(input.value.length >= input.getAttribute('maxlength'))
      input.nextElementSibling.focus();
  });
})
Related