I have a search component in my app and when the user input some texts it filters data based on the user input and shows a list of filtered data. What i want to do is to make the text that is searched by the user bold in the filtered data. So for example if i search 'Jo', the filtered data should show as Jo hn / Jo seph / Jo e Rogan
i can figure out a way to make the entire word bold but cannot figure out a way to bold only the part where user typed.
Pretty simple. Just split and join with bold or strong tag.
let searchStr = "Jo"
name.split(searchStr ).join('<b>'+ searchStr +'</b>');
let searchStr = "Jo"; let name = "John"; document.getElementById('res').innerHTML = name.split(searchStr).join('<b>'+ searchStr +'</b>');
<h2>Searching "Jo" in John</h2> <p id="res"></p>
You want to change how each string in the filtered data is rendered, based on the search term.
You can use the search term to create a regex, then add <strong>
tags to each string based on the regex.
If you don't want to use dangerouslySetInnerHtml
then you can do something like this:
const data = ["John", "Banjo", "Jojo", "Bob Jones", "John Johnson", "James"];
const searchTerm = "jo";
const searchTermRegex = new RegExp(
// Escape special regex characters in the search term,
// otherwise you will get an invalid regex
`(${searchTerm.replace(/[.\\+*?[^\]$(){}=!<>|:-]/g, "\\$&")})`,
"gi"
);
const getBoldFilteredText = (text, term) => {
const substrings = text.split(searchTermRegex);
return (
<div>
{substrings.map((substring) =>
substring.toLowerCase() === term.toLowerCase() ? (
<strong>{substring}</strong>
) : (
substring
)
)}
</div>
);
};
return <div>{data.map((s) => getBoldFilteredText(s, searchTerm))}</div>;
Here's a way of doing it that doesn't use dangerouslySetInnerHTML
or open you up to XSS attacks.
Explanation: String#split
with a regex capturing group ( /(...)/
) includes the captured text in the results at odd-numbered indexes. For example, 'baba'.split(/(b)/)
gives you ["", "b", "a", "b", "a"]
. Once you have these results, you can map the odd (matched) results to strong
elements and the even ones to React.Fragment
s.
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#Escaping
const regexEscape = str => str.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&')
const boldify = searchStr => targetStr => {
return targetStr
.split(new RegExp(`(${regexEscape(searchStr)})`, 'i'))
.map((part, idx) =>
idx % 2 ? (
<strong key={idx}>{part}</strong>
) : (
<React.Fragment key={idx}>{part}</React.Fragment>
)
)
}
const SearchForm = () => {
const [searchStr, setSearchStr] = useState('');
return (
<form onSubmit={e => e.preventDefault()}>
<input
type='text'
value={searchStr}
onChange={e => setSearchStr(e.currentTarget.value)}
/>
<ul>
{list.map(item => {
return <li>{boldify(searchStr)(item)}</li>;
})}
</ul>
</form>
)
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.