0

I have a React Native App and i have a Search Bar and a FlatList. When I Search something in the SearchBar the text has to be highlighted in the list.

Single string search works fine:

But now when I type "visit hour" neither visit or hour gets highlighted

I am using a function for highlighting the text. SearchBar value is stored as this.state.value and I am passing it as props. The logic I am using inside renderItem of Flatlist is as below

getHighlightedText = text => {
  const {value} = this.props
  const parts = text.split(new RegExp(`(${value})`, 'gim'));
  console.log('split:', parts);
  return (
    <Text>{parts.map(part => (
      part.toLowerCase() === value.toLowerCase()) ?
        <Text style = {{backgroundColor: 'red'}}>{part}</Text> :
        part)}
    </Text>
  );
}
return <Text>{getHighlightedText(Desc)}</Text>;

This works fine when I search one word. For Example if my flat list has 2 items - "My Dog" and "Her Cat". If my Search Text is "Dog" then Dog is highlighted in red. But if I Search "M Dog" or "M D" then nothing gets Highlighted. It has to highlight characters rather than words. Please help me fix the code!!!!!

Updated my code

So I will be splitting the search value and then try to highlight for each search text. if I enter "visit hour" its split into "visit" and "hour". For some reason the loop executed only for "visit" and not "hour". Some mistake in my code. I have only added a for loop. Please help!!! :

getHighlightedText = text => {
  // search value is split and stored in val array. "list" and "hour"
  const val = value.split(' ');

  // below my item Description is split based on my search
  // terms "visit" n "hour" and then stored in vals array
  const vals = val.map(valu => {.
    var regex = new RegExp(`(${valu})`, 'gim');
    return text.split(regex);
  })

  // vals is merged into 1 array
  const merged = [].concat.apply([], vals);

  // below I am looping for each of my search text 1st
  // "visit" then "hour"         
  for (i = 0; i < val.length; i++) {
    const l = val[i];

    return (
      <Text>{merged.map(part => (
          part.toLowerCase() === l.toLowerCase()) ?
          <Text style = {{backgroundColor: 'red'}}>{part}</Text> :
          part
        )}
      </Text>
    );
  }
}

// using my getHighlightedText in my renderItem
return <Text>{getHighlightedText(Desc)}</Text>;

Loop is getting terminated because of the return statement. "visit" is highlighted but "hour" is not as the loop never reached "hour".

Help please!!!

grooot
  • 446
  • 2
  • 10
  • 31
  • What is `const parts = text.split(regex);` doing? And you return twice? Is it work? Or render different text below the screen? – 高鵬翔 Apr 29 '20 at 08:25
  • It is splitting my Desc of each item that is "Test Message - visiting hour". It's splitting based on my search value. – grooot Apr 29 '20 at 10:09

1 Answers1

0

Just use string.includes(substring) insteads === .

Because using === represent the same value. But includes just need "contains".

This may solved your problem, take it a try. :)

return (
  <Text>{parts.map(part => (value.toLowerCase().includes(part.toLowerCase())) ?
      <Text style={{backgroundColor: 'red'}}>{part}</Text> : part)}
  </Text>);
}

UPD1:

If your want to achieve similar effect, I would suggest you to split the search string by .split(" "); to array, and map each string in array to highlight

UPD2:

You don't have to using for loop! Just add it in to your condition something like:

{parts.map(part =>
  (part[0].toLowerCase() === valu.toLowerCase()
  || part[1].toLowerCase() === valu.toLowerCase()) // change to your parameter
高鵬翔
  • 1,997
  • 2
  • 8
  • 21
  • tried that and it did not work. Guess the issue is with my RegExp. tried \s \\s too. Updated my question with images of my search bar. – grooot Apr 29 '20 at 07:52
  • Guess I have to split my search value inside the getHighlightedText function and then highlight it individually. If my search value is "Visit hour" I should split it into "List" and "hour" and then pass this individual values. Do you think it will work?? – grooot Apr 29 '20 at 07:54
  • I have seen your new question, but it should be not highlight! According to your logic, it should highlight most of the word if I search:"our ing age". It really weird. I have update the answer to suggest. – 高鵬翔 Apr 29 '20 at 08:04
  • It should be highlight like searching : "visiting-hour" or "visiting, hour" – 高鵬翔 Apr 29 '20 at 08:06
  • yes I have added a For loop (see my updated question) some issue with it. – grooot Apr 29 '20 at 08:17
  • You don't need to add a for loop, I have update my answer. – 高鵬翔 Apr 29 '20 at 08:30
  • no I cannot do that. As we won't know how the user might enter the text. They can enter like "vis hou Test". Need something dynamic. – grooot Apr 29 '20 at 08:38
  • You can use [nested map](https://stackoverflow.com/questions/51615559/react-map-over-nested-array-of-objects) – 高鵬翔 Apr 29 '20 at 08:55