Highlighting a filtered result in AngularJS

2019-01-10 09:28发布

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 parsed the page on key up on the input, but I'm trying to do it the angular way. Any ideas ?

My code :

<input id="search" type="text" placeholder="Recherche DCI" ng-model="search_query" autofocus>
<tr ng-repeat="dci in dcis | filter:search_query">
            <td class='marque'>{{dci.marque}} ®</td>
            <td class="dci">{{dci.dci}}</td>
 </tr>

13条回答
我想做一个坏孩纸
2楼-- · 2019-01-10 09:57

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.

查看更多
够拽才男人
3楼-- · 2019-01-10 09:57

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:

  • valid: m
  • invalid: m[
  • invalid: m[ô
  • invalid: m[ôo
  • valid: m[ôo]
  • valid: m[ôo]n
  • valid: m[ôo]ni
  • valid: m[ôo]nic
  • valid: m[ôo]nica

What do you think @Mik Cox?

查看更多
对你真心纯属浪费
4楼-- · 2019-01-10 10:00

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>
查看更多
Fickle 薄情
5楼-- · 2019-01-10 10:05

Thanks for asking this as it was something I was dealing with as well.

Two things though:

First, The top answer is great but the comment on it is accurate that highlight() has problem with special characters. That comment suggests using an escaping chain which will work but they suggest using unescape() which is being phased out. What I ended up with:

$sce.trustAsHtml(decodeURI(escape(text).replace(new RegExp(escape(search), 'gi'), '<span class="highlightedText">$&</span>')));

Second, I was trying to do this in a data bound list of URLs. While in the highlight() string, you don't need to data bind.

Example:

<li>{{item.headers.host}}{{item.url}}</li>

Became:

<span ng-bind-html="highlight(item.headers.host+item.url, item.match)"></span>

Was running into problems with leaving them in {{ }} and getting all sorts of errors.

Hope this helps anybody running into the same problems.

查看更多
放荡不羁爱自由
6楼-- · 2019-01-10 10:06

If you are using the angular material library there is a built in directive called md-highlight-text

From the documentation:

<input placeholder="Enter a search term..." ng-model="searchTerm" type="text">
<ul>
  <li ng-repeat="result in results" md-highlight-text="searchTerm">
    {{result.text}}
  </li>
</ul>

Link to docs: https://material.angularjs.org/latest/api/directive/mdHighlightText

查看更多
冷血范
7楼-- · 2019-01-10 10:12

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">
查看更多
登录 后发表回答