2

I'm building a simple interface where user enters an input in textarea and a search item in an input. Output should highlight substrings of text provided in the search item area.

const Highlighter = () => {
  const [myPara, setMyPara] = useState("");
  const [searchTerm, setSearchTerm] = useState("");
  const [caseSensitive, setCaseSensitive] = useState(true);
  
  const onUpdateText = (event) => {
    setMyPara(event.target.value);
  }
  
  const onUpdateSearch = (event) => {
    setSearchTerm(event.target.value);
    console.log(caseSensitive)
  }
  
  const onUpdateCaseSensitive = (event) => {
    setCaseSensitive(!caseSensitive)
    console.log(caseSensitive)
  }
  
  const getHighlightedText = (toHighlight) => {
    const myText = myPara.split('');
    const searchString = toHighlight.split('');
    
    return (
      <span>
        {myText.filter(String).map((part, i) => {
          return part.includes(searchString) ? (
            <mark key={i}>{part}</mark>
          ) : (
            <span key={i}>{part}</span>
          );
        })}
      </span>
    );
  }
  
  return (
    <>
      <textarea data-testid="source-text" value={myPara} onChange={onUpdateText} />
      <br/>
      <input data-testid="search-term" value={searchTerm} onChange={onUpdateSearch}  />
      <br/>
      case sensitive? <input type="checkbox" data-testid="case-sensitive" defaultChecked={true} onChange={onUpdateCaseSensitive}  />
      <br/>
      <div data-testid="result">{getHighlightedText(searchTerm)}</div>
    </>
  );
};

export default Highlighter;

My attempt is as above. However it is not highlighting any string whatsoever. Can anybody help me spot the error?

Thanks.

Ashar
  • 724
  • 10
  • 30

1 Answers1

0

I tested your component and it works if you search only for one letter. You are splitting your text into letters and map letters. Includes is not supposed to work with array of letters.

You will need another approach to search your string maybe with regex : Search for all instances of a string inside a string

I think then, once you have the indexes of the occurrences of your search. You will have to map you string and highlight the indexes found + the following letters depending on the size of your search.

Rémi Girard
  • 305
  • 3
  • 10