How to disable tab button for specific inputs in ReactJS?

Viewed 7559

I have inputs on a few pages which I animate through. You have to click the button to get the next page and the next round of inputs, however when you get to the end of each page, you can hit the tab button and it focuses on the next input field which throws off the animation flow and display. Can I disable the tab button?

3 Answers

If all you want to do is prevent the field from receiving focus from a tab, you can set the tabIndex attribute to -1.

<form>
  <input type="text" />
  <input type="text" />
  <button>button</button>
  <input type="text" tabIndex="-1" />
</form>

If your goal is to disable "tabbing out" of an input field, you can listen to the keyDown event, and if the keyCode is 9 (value for Tab), then preventDefault on the event:

function MyComponent() {
  return <input onKeyDown={(e) => { if (e.keyCode === 9) e.preventDefault() }} />
}

Rest of your code stays the same; i.e. however you handle input change:

function MyComponent() {
  const [value, setValue] = React.useState('');
  return (
    <input
      value={value}
      onChange={(e) => setValue(e.target.value)}
      onKeyDown={(e) => {
        if (e.keyCode === 9) e.preventDefault();
      }}
    />
  );
}

From an accessibility and user experience perspective, I'd suggest not disabling Tab functionality. Some of your users might not have a mouse/touch input device or capability, or might want or prefer to use the keyboard exclusively for navigation. Tab is the natural way to advance among inputs, links, and buttons on web pages and it's best if you can preserve the functionality. Is there a way to deliver your animation experience while preserving Tab navigation?

Here's a sandbox to show you how to do this using React refs. Essentially, you can use the ref to store the DOM element you want to modify, making it really reusuable. In this case we just want to set that input's tabIndex to -1

https://codesandbox.io/s/vigilant-fermat-vihnc

function App() {
  const skipInputRef = React.createRef();

  useEffect(() => {
    skipInputRef.current.tabIndex = -1;
  }, []);

  return (
    <div className="App">
      <input />
      <input />
      <input ref={skipInputRef} placeholder="skip" />
      <button>Click</button>
    </div>
  );
}
Related