0

I am trying to focus and then click input field with the help of useRef hook. What I am trying to achieve is to open the keyboard of input field in mobile phone browser of both IOS and ANDROID. Unfortunately it doesn't work in my case and I am not sure why. Note that console log shows clicked. Here is my code:

import React, { useEffect, useRef } from "react";
import ReactDOM from "react-dom";

const App = () => {
  const inputRef = useRef();

  useEffect(() => {
    waiting();

    inputRef.current.click();
  }, []);

  const waiting = async () => {
    await inputRef.current.focus();
  };
  return (
    <div>
      <input
        ref={inputRef}
        placeholder="input area"
        type="tel"
        onClick={() => {
          console.log("clicked");
        }}
      />
    </div>
  );
};

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

I am trying to reimplement this javascript code by n8jadams IOS show keyboard on input focus in React. Not sure if I am on the right track. This code will ensure that Keyboard will open both on IOS and ANDROID

UPDATE:

got this code but it still doesn't work:

import React, { useEffect, useRef } from "react";
import ReactDOM from "react-dom";

const App = () => {
  const inputRef = useRef();
  function focusAndOpenKeyboard(el) {
    if (el) {
      // Align temp input element approx. to be where the input element is
      var __tempEl__ = document.createElement("input");
      __tempEl__.style.position = "absolute";
      __tempEl__.style.top = el.offsetTop + 7 + "px";
      __tempEl__.style.left = el.offsetLeft + "px";
      __tempEl__.style.height = 0;
      __tempEl__.style.opacity = 0;
      // Put this temp element as a child of the page <body> and focus on it
      document.body.appendChild(__tempEl__);
      __tempEl__.focus();

      // The keyboard is open. Now do a delayed focus on the target element
      setTimeout(function () {
        el.focus();
        el.click();
        // Remove the temp element
        document.body.removeChild(__tempEl__);
      }, 100);
    }
  }
  useEffect(() => {
    const element = inputRef.current.querySelector("input, textarea");
    focusAndOpenKeyboard(element);
  }, [inputRef]);

  return (
    <div ref={inputRef}>
      <input placeholder="input area" type="tel" />
    </div>
  );
};

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Sonny49
  • 425
  • 3
  • 18

1 Answers1

0

I had the same issue last week and was able to resolve it after multiple days of searching and trying different approaches including the one you tried aswell. The big point that made a difference to me was the following sentence of this blog post:

The useEffect handler won’t actually run, since React won’t re-render after the ref gets attached. In this situation, the React documentation recommends using a callback ref instead.

So I tried it like so:

const input = useRef();

// Puts searchbar in focus on render if mobile and opens the keyboard on both iOS and Android devices
// Source: https://blog.maisie.ink/react-ref-autofocus/#callback-refs
const callbackRef = useCallback(
    (inputElement: HTMLInputElement): void => {
        input.current = inputElement;
        focusAndOpenKeyboard(inputElement, 150);
    },
    [],
);

return (
<div>
  <input placeholder="input area" type="tel" ref={callbackRef}/>
</div>

);

I hope this helps you even though my answer is a lot later than your question.