I\'m using a ng-repeat and filter in angularJS like the phones tutorial but I\'d like to highlight the search results in the page. With basic jQuery I would have simply pars
I hope my light example will make it easy to understand:
app.filter('highlight', function() {
return function(text, phrase) {
return phrase
? text.replace(new RegExp('('+phrase+')', 'gi'), '<kbd>$1</kbd>')
: text;
};
});
<input type="text" ng-model="search.$">
<ul>
<li ng-repeat="item in items | filter:search">
<div ng-bind-html="item | highlight:search.$"></div>
</li>
</ul>
My solution for highlight, used this with angular-ui-tree element: https://codepen.io/shnigi/pen/jKeaYG
angular.module('myApp').filter('highlightFilter', $sce =>
function (element, searchInput) {
element = element.replace(new RegExp(`(${searchInput})`, 'gi'),
'<span class="highlighted">$&</span>');
return $sce.trustAsHtml(element);
});
Add css:
.highlighted {
color: orange;
}
HTML:
<p ng-repeat="person in persons | filter:search.value">
<span ng-bind-html="person | highlightFilter:search.value"></span>
</p>
And to add search input:
<input type="search" ng-model="search.value">
About the problems with special caracter, I think just escaping you might lose regex search.
What about this:
function(text, search) {
if (!search || (search && search.length < 3)) {
return $sce.trustAsHtml(text);
}
regexp = '';
try {
regexp = new RegExp(search, 'gi');
} catch(e) {
return $sce.trustAsHtml(text);
}
return $sce.trustAsHtml(text.replace(regexp, '<span class="highlight">$&</span>'));
};
An invalid regexp could be user just typing the text:
What do you think @Mik Cox?
angular ui-utils supports only one term. I'm using the following filter rather than a scope function:
app.filter('highlight', function($sce) {
return function(str, termsToHighlight) {
// Sort terms by length
termsToHighlight.sort(function(a, b) {
return b.length - a.length;
});
// Regex to simultaneously replace terms
var regex = new RegExp('(' + termsToHighlight.join('|') + ')', 'g');
return $sce.trustAsHtml(str.replace(regex, '<span class="match">$&</span>'));
};
});
And the HTML:
<span ng-bind-html="theText | highlight:theTerms"></span>
Use ng-class that is applied when the search term is related to the data the element contains.
So on your ng-repeated elements, you'd have ng-class="{ className: search_query==elementRelatedValue}"
which would apply class "className" to elements dynamically when the condition is met.
There is standart Highlight filter in the angular-bootstrap: typeaheadHighlight
Usage
<span ng-bind-html="text | typeaheadHighlight:query"></span>
With scope {text:"Hello world", query:"world"}
renders in
<span...>Hello <strong>world</strong></span>