Highlighting search result improves the user experience and makes the search process less time consuming compare to showing the search result only.
We are very familiar with this feature, it is available in almost every browser, rich text editors and document processor like Google docs.
In this tutorial i am going to explain you how to develop the highlight feature using AngularJs filter module.
Our approach to develop this system is straightforward. Filter module allows use to provide live search for the given data bind with $scope.
We will extend filter module to determine the way to extract the matched search phrases and then simply replace those matched phrases with span tag colored as green or something.
To extract search phrases from $scope data i used simple regular expression.
Code:
We are using simple HTML tags and filter module of angular to perform search. HTML code are placed in index.html and Angular code is in app.js.
<html>
<head>
<script src="angular.js"></script>
<script src="app.js"></script>
<style>
.highlighted { background: yellow }
</style>
</head>
<body ng-app="Demo">
<h1>Highlight text using AngularJS.</h1>
<div class="container" ng-controller="Demo">
<input type="text" placeholder="Search" ng-model="search.text">
<ul>
<div ng-repeat="item in data | filter:search.text"
ng-bind-html="item.text | highlight:search.text">
</div>
</ul>
</div>
</body>
</html>
Here is our Angular code to highlight filter result.
.controller('Demo', function($scope) {
$scope.data = [
{ text: "<< ==== Put text to Search ===== >>" }
]
})
.filter('highlight', function($sce) {
return function(text, phrase) {
if (phrase) text = text.replace(new RegExp('('+phrase+')', 'gi'),
'$1')
return $sce.trustAsHtml(text)
}
})
Explanation:
Observe code shown below. I am performing filter operation by binding textbox to it. So when you type anything in textbox, data present in $scope.data will be filter accordingly.
ng-bind-html="item.text | highlight:search.text">
div>
In angular code i extended filter module which returns the matched Search and if the input present in filter keyword is similar to the one filter found we will replace it with SPAN which in turn hold the matched search data placed in $1.
'$1')
Enhancement:
We can proceed with performing search on dynamic data and highlighting the found key. To do that you can use any backend technology like Node.js, PHP to perform database operation and bind the data in $scope variable.
Our code will work with whatever content present in $scope.data. You can either put static content on it or dynamic content depend upon your application.
You can use this code in web application such as text processor ( Like Google docs ) or any sort of search where your main goal is to help user find information quickly.
Further reading:
There is one rich library on angular called UI.UTILS which contains many GUI interaction code. Have a look on this.
External link : UI.UTILS home page.
Conclusion:
Highlighting a text so that user can quickly find it is really very powerful approach to improve interaction with your application. This small piece of code may help you to achieve or at least gives you a kick start !
Hey – nice article. I’m an angular newb. I’m having trouble implementing this. Will this work if I’m pulling the text I want to search in using ajax from a local json file? Here is my code – any thoughts would be tremendously appreciated.
Thanks,
Rich
//My controller
var testControllers = angular.module(‘testControllers’, []);
testControllers.controller(‘ListController’, [‘$scope’,’$http’, ‘$location’, function($scope, $http, $location) {
$http.get(‘js/data.json’).success(function(data) {
$scope.tests = data;
$scope.filter(‘highlight’, function($sce) {
return function(text, phrase) {
if (phrase) text = text.replace(new RegExp(‘(‘+phrase+’)’, ‘gi’),
‘$1’)
return $sce.trustAsHtml(text)
}
})
});
$scope.pageClass = ‘page-search’;
$scope.pageTitle = ‘Information Center’;
}]);
//html
div class=”search-container” ng-show=”showSection(1)”>
Go To Test
CPT Codes: {{test.cptCodes}}
my html code didn’t seem to come over. sorry.
Hi Rich,
I think this should work.
Nice concise and clean implementation, used this as basis for my needs to use one-or-more phrases to and an arbitrary tag, passing both the tag name and the phrases (one string or an array of strings) as arguments to the filter:
(HTML tags below are missing brackets only so they don’t get filtered out of my comment, and in code sample, LT and GT placeholders are used)
view:
div ng-bind-html="myForm.invited | tagmatch: 'rsvp' : myCtrl.confirmed"
filter:
GeSHi Error: GeSHi could not find the language javscript (using path /home/codeforgeek.com/public_html/wp-content/plugins/codecolorer/lib/geshi/) (code 2)
sample inputs:
tagname: 'rsvp' // app.css: rsvp {font-weight: bold; }
phrases: myCtrl.confirmed // ['Paul','Ringo']
result (simplified):
John rsvpPaul/rsvp George rsvpRingo/rsvp
Obviously one can use a different wrapper for the matched phrases, but in my case, was simpler to just use an arbitrary HTML tag (also because I need to parse OUT that tag for a subsequent transformation, so simpler to go after a tag instead of a span-with-class combo)
Performance does not seem to be a problem, but can probably be tuned further.
(apologies if there’s a syntax error in the above after I sanitized my code for example-ness, but one gets the idea I hope … put angle brackets back in where appropriate, etc.)