Reputation: 466
I have been testing my React-native App's front-end and found some issue.
There is a SearchBar that highlights the text in the Search result as shown below.
But when i try to search "( )[ ] ! + , . & %" and many more the character is displayed in the search result but not highlighted. I am guessing this has something to do with RegExp.
The Highlight function code:
escape = function( value ) {
return value.replace(/[\-\[\]{}()*+?.,\\\^$%#\s]/g, "\\$&");
}
getHighlightedText(text){ // Highlight logic
const {value} = this.props;
if(value == "" || value == null || value == 0){
return <Text> {text} </Text>
}
else{
const words = value.split(/\s+/g).filter(word => word.length);
const pattern = words.join('|');
const tex = escape(pattern);
const re = new RegExp(tex, 'gi')
const children = [];
let before, highlighted, match, pos = 0;
const matches = text.match(re);
if(matches != null){
for( match of matches ){
match = re.exec(text)
if(pos < match.index) {
before = text.substring(pos, match.index);
if(before.length){
children.push(before)
}
}
highlighted = <Text style={{ backgroundColor: 'coral'}} key={match.index + match[0].length}>{match[0]}</Text>
children.push(highlighted);
pos = match.index + match[0].length;
}
}
if(pos < text.length){
const last = text.substring(pos);
children.push(last);
}
return <Text>{children}</Text>
}
render() {
<Text> {value !== "" ? this.getHighlightedText(text) : text} </Text>
}
I want all the characters to be highlighted.
Any suggestion would be great to rectify this issue.
Upvotes: 1
Views: 937
Reputation: 156
Your answer is in the first line of your code!
Why you're using "escape" function? you're removing special characters in your code before highlight
escape = function( value ) {
return value.replace(/[\-\[\]{}()*+?.,\\\^$%#\s]/g, "\\$&");
}
This is a cleaner version and better version of your code :
const Highlighted = ({text = '', highlight = ''}) => {
if (!highlight.trim()) {
return <Text>{text}</Text>;
}
const regex = new RegExp(`(${_.escapeRegExp(highlight)})`, 'gi');
const parts = text.split(regex);
return (
<Text>
{parts
.filter(part => part)
.map((part, i) =>
regex.test(part) ? (
<Text style={{backgroundColor: '#fcf8e3'}} key={i}>
{part}
</Text>
) : (
<Text key={i}>{part}</Text>
),
)}
</Text>
);
};
and then
<Highlighted
text={allTextsHere}
highlight={
searchTermHere}
/>
Upvotes: 2