Flutter: Highlight Searched Text

+ JavaScript: return searched portion of text

In this post, I’ll go over how I highlighted a search text in user’s search results. I did manage to create a search method on Node.js, which is sending the above search results back to Flutter (which I’ll write at the end of the post).

Below is my highlightedText method that returns what you see in the above picture, utilizing TextSpan, RichText (in the view), and RegExp. It receives the searchText and the whole text as its parameters.

(1) I replace all new lines with “…” in case there are any.

(2) I convert the searchText to a RegExp in order to utilize its .allMatches(your whole text) method. If there are any matches in your text that matches the searchText, the method returns a list of Match, which has the .start and .end getters for the starting and ending indices. Make sure to explore the optional parameters in RegExp class.

(3) Next, I prepare an exception handler in case there are 0 matches, because otherwise, continuing on below will cause an error.

(4) The for-loop utilizes the below method, which returns a TextSpan with a different background color depending on its boolean parameter.

(5) In the for-loop, there are 3 separate parts:
- the first part is the portion from the beginning of the whole text until the first match, which does not need to be highlighted.
- the second part is the match itself, which does need to be highlighted.
- the third part is a conditional for when the for-loop is at its last loop and there is remaining text after the last match.end.

(4) The for-loop’s _startIndex starts at 0, which is the beginning of the whole text, and after each loop, it needs to be set to match.end of the match that the loop is on.

Done!

The List<TextSpan> is returned to my view, and shown using RichText.

view

Node.js / JavaScript — Search

Below is my code for returning portion of a text with the searched text. This code already assumes that you’ve found a match of the searchText in the text.

const sentence = (text, searchText) => {
const searchRegExp = new RegExp(searchText, "gi");
const index = searchRegExp.exec(text).index;
const lastPeriod = text.substring(0, index).lastIndexOf(".") + 1;

let nextPeriod = text.indexOf(".", index + searchText.length) + 1;
if (nextPeriod == 0) nextPeriod = text.length;
let searchSentence = text.substring(lastPeriod, nextPeriod).trim();

if (searchSentence.length < 250) {
nextPeriod = text.indexOf(".", lastPeriod + searchSentence.length) + 1;
if (nextPeriod == 0) nextPeriod = text.length;
searchSentence = text.substring(lastPeriod, nextPeriod).trim();
}
if (nextPeriod < text.length) searchSentence += " ...";
return searchSentence;

}

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store