Friday 22 October 2021

How to properly control focus and blur events on a React-Bootstrap InputGroup?

I have a single input element from react-bootstrap that will allow the user to change the field value and 2 buttons will appear, one to accept the changes and the other will cancel the changes leaving the original value in.

I manage to control the focus and blur events by delegating the listeners to the wrapping component, my thinking is that since the focus is still within the wrapping component, I won't lose its focus, but pressing the inner buttons seems to blur the focus, therefore the Accept and Cancel buttons don't fire any events...

Here is my code example:

Edit Edit Cell Form

import { useState, useEffect, useRef } from "react";
import { InputGroup, Button, FormControl } from "react-bootstrap";

import "./styles.css";

const InputField = ({ title }) => {
  const formRef = useRef(null);
  const [value, setValue] = useState(title);
  const [toggleButtons, setToggleButtons] = useState(false);

  const onChange = (e) => {
    setValue(e.target.value);
  };

  const onFocus = () => {
    setToggleButtons(true);
  };

  const onBlur = () => {
    setToggleButtons(false);
  };

  const acceptChange = () => {
    console.log("Accept");
    setToggleButtons(false);
  };

  const cancelChange = () => {
    console.log("Cancel");
    setToggleButtons(false);
  };

  useEffect(() => {
    const form = formRef.current;
    form.addEventListener("focus", onFocus);
    form.addEventListener("blur", onBlur);

    return () => {
      form.removeEventListener("focus", onFocus);
      form.removeEventListener("blur", onBlur);
    };
  }, []);

  return (
    <div className="App">
      <InputGroup className="m-3" style=>
        <FormControl
          ref={formRef}
          value={value}
          onChange={onChange}
          // onFocus={onFocus}
          // onBlur={onBlur}
        />
        {toggleButtons ? (
          <InputGroup.Append>
            <Button variant="outline-secondary" onClick={() => acceptChange()}>
              Accept
            </Button>
            <Button variant="outline-secondary" onClick={() => cancelChange()}>
              Cancel
            </Button>
          </InputGroup.Append>
        ) : null}
      </InputGroup>
    </div>
  );
};

export default function App() {
  return (
    <>
      <InputField title={"Input 1"} />
      <InputField title={"Input 2"} />
      <InputField title={"Input 3"} />
      <InputField title={"Input 4"} />
    </>
  );
}


from How to properly control focus and blur events on a React-Bootstrap InputGroup?

No comments:

Post a Comment