Show highlighted text in input

164 Views Asked by At

I'm trying to do something like below i.e I've an input with suggestions dropdown , there are only 2 values in this Male and Female If i type M the remaining letters ale shows highlighted in input and by clicking on it or pressing tab it gets autopopulate vice versa for female Is there any library for it ?

I've tried below code but it doesn't show any highlighted text for obvious reason and autopopulate whenever used type M or F , the problem is it doesn't let me erase the values due to such conditions below

ps. I'm attaching an image for reference of what I want , its a feature in gmail search gmail search feature

if (name === 'patient_gender') {
        if (input.toLowerCase().startsWith('m')) {
            input = 'Male';
        } else if (input.toLowerCase().startsWith('f')) {
            input = 'Female';
        }
    }
1

There are 1 best solutions below

0
ramoneguru On

It's a touch tricky and it looks like google uses 2 input boxes, does some z-index'ing switches, and then a few other things like capturing right arrow/tab to autocomplete and such.

I have a very rough demo and the code is posted here for posterity. You'll have to fill in the missing parts, but hopefully this gives you a start.

Sandbox link

import React from "react";
import "./styles.css";

export default function App() {
  const [userInput, setUserInput] = React.useState<string>("");
  const [autoInput, setAutoInput] = React.useState<string>("");
  const [userInputStyle, setUserInputStyle] = React.useState({ left: "0" });
  const [autoInputStyle, setAutoInputStyle] = React.useState();
  const MALE = "ale";
  const handleInputChange = (e) => {
    const str = e.target.value;
    if (str === "m") {
      // hardcoded width for demo, but useRef would  be better to get a more exact width
      const autoInputStyleChange = { right: 0, width: "458px" };
      const userInputStyleChange = { zIndex: "1" };
      setAutoInput(MALE);
      setUserInputStyle(userInputStyleChange);
      setAutoInputStyle(autoInputStyleChange);
    }
    setUserInput(str);
  };

  return (
    <div className="App">
      <h1>Test Input</h1>
      <form>
        <section className="input-wrapper">
          <input
            style={userInputStyle}
            className="user-input"
            type="text"
            value={userInput}
            onChange={handleInputChange}
          />
          <input
            style={autoInputStyle}
            className="auto-input"
            type="text"
            placeholder={autoInput}
          />
        </section>
      </form>
    </div>
  );
}

Basic CSS

.input-wrapper {
  position: relative;
  width: 100%;
}

.user-input,
.auto-input {
  position: absolute;
  top: 0;
  z-index: 5;
  border: 0;
  width: 100%;
}

.user-input {
  z-index: 6;
  left: 0;
  border: 1px solid blue;
  color: blue;
}

.auto-input {
  top: 1px;
  border: 0;
  outline: none;
  padding: 1px 0;
}