How can I prevent onBlur event from firing?

Viewed 2677

I am trying to build an input with a dropdown that provides suggestions. I have an input element that uses onBlur, which technically when click outside will remove the ul element. When I click on the ul element, it also removes the ul element, which fires the onBlur event on the input. Is there a way to implement onBlur that prevents the ul element to fire the onBlur event?

import React, { useState, useEffect, useRef } from "react";

import "./styles.css";

const Autocomplete = (props) => {
  const [userInput, setUserInput] = useState("");

  const [listResults, setListResults] = useState([]);

  const [openModal, setOpenModal] = useState(false);

  useEffect(() => {
    const filteredResults = props.options.filter((option) =>
      option.includes(userInput)
    );

    setListResults(filteredResults);
  }, [userInput, props.options]);

  const handleInput = (event) => {
    setUserInput(event.target.value);
  };

  const handleInputClick = () => {
    setOpenModal(!openModal);
  };

  const handleClickOption = (data) => {
    setUserInput(data);
    setOpenModal(false);
    ulEl.current.focus();
  };

  return (
    <div className="container">
      <input
        name="search-input"
        value={userInput}
        onChange={handleInput}
        autoComplete="off"
        onFocus={handleInputClick}
        onBlur={handleInputClick}
      />
      <ul className="search-list">
        {openModal &&
          listResults &&
          listResults.map((data, key) => (
            <li
              key={key}
              onClick={() => {
                handleClickOption(data);
              }}
            >
              {data}
            </li>
          ))}
      </ul>
    </div>
  );
};

export default Autocomplete;

Any help will be greatly appreciated

2 Answers

Short answer, just add this to your element

onMouseDown={(e) => e.preventDefault()}

In this situation, call event.preventDefault() on the onMouseDown event. onMouseDown will cause a blur event by default, and will not do so when preventDefault is called. Then, onClick will have a chance to be called. A blur event will still happen, only after onClick.

You may use the list attribute of <input> with a <datalist> instead of using a <ul>.

Hope this suits your case.

Related