Example of Highlighting Search Keywords in Angular

  • 2021-08-05 08:43:37
  • OfStack

In Angular, we should not try to modify the contents of DOM directly. When we need to update the contents of DOM, we should modify our data model, that is, the data in $scope. Angular will help us display the modified data in the page.

However, in some cases, for example, we have a search box and want to highlight the search keywords in the text, which will feel more difficult. filter can help us deal with this situation.

In fact, most of the time, our data can't be directly output to DOM, such as date, currency, etc. Usually, we need to format our internal data and then output it to the page. In Angular, this work is realized through filter.

filter is an module level service. After definition, it can be directly used in the whole module, which has high reusability.

To illustrate, review the Walk into AngularJs (7) Filter under 1 (filter) Filter under 1, and then explain in detail how to handle the search keyword highlighting problem. You can start directly from the Custom Filter section.

1. Use of filters

1. Use in the template

We can use filter directly in {{}}, following the expression with a partition, with the following syntax:


{{ expression | filter }}

Multiple filter can also be used together, and the output of the previous filter will be the input of the next filter.


{{ expression | filter1 | filter2 | ... }}

filter can receive parameters, which are separated by:.


{{ expression | filter:argument1:argument2:... }}

In addition to formatting the data in {{}}, we can also use filter in instructions, such as filtering the array array first and then recycling the output:


<span ng-repeat="a in array | filter ">

2. Use in controller and service

Filters can also be used in our js code in the familiar form of dependency injection, such as the currency filter I want to use in controller, just inject it into that controller.


app.controller('testC',function($scope,currencyFilter){
  $scope.num = currencyFilter(123534); 
}

Using {{num}} in the template, you can directly output $123,534.00! The same is true of using filter in services.

At this point, you may wonder, if I want to use multiple filter in controller, do I need to inject one by one? Wouldn't it be too laborious? Don't worry, little brother ~ ng provides a $filter service to call the required filter. You only need to inject a $filter. The usage method is as follows:


app.controller('testC',function($scope,$filter){
  $scope.num = $filter('currency')(123534);
    $scope.date = $filter('date')(new Date()); 
}

2. Built-in filter

1. currentcy, use currency to format numbers into currency, default is dollar sign, you can pass in the required symbol


{{num | currency : ' $ '}}

2. date, the native js has limited formatting ability for dates, and the date filter provided by ng can basically meet the formatting requirements.


{{date | date : 'yyyy-MM-dd hh:mm:ss EEEE'}}

3. filter, be careful, the name of this filter is filter, don't get confused. Used to process an array, and then you can filter out elements containing a substring and return them as a subarray. It can be an array of strings or an array of objects. If it is an array of objects, it can match the value of attributes. It takes 1 parameter, which is used to define the matching rules of substrings.


$scope.childrenArray = [
    {name:'kimi',age:3},
    {name:'cindy',age:4},
    {name:'anglar',age:4},
    {name:'shitou',age:6},
    {name:'tiantian',age:5}
  ];

Custom helper functions.


$scope.func = function(e){return e.age>4;}

Use the filter filter


{{ expression | filter1 | filter2 | ... }}
0

4. json, formatting the json object. The json filter can format an js object as an json string. The effect is similar to the familiar JSON. stringify () 1.


{{ expression | filter1 | filter2 | ... }}
1

5. limitTo, limitTo filters are used to truncate arrays or strings and take 1 parameter to specify the length of the truncation. You can only intercept from the beginning of an array or string


{{ expression | filter1 | filter2 | ... }}
2

6. lowercase, converted to lowercase. Convert the data to all lowercase.

7. uppercase, converted to uppercase.

8. number, formatted numbers. The number filter can divide 1 digit with thousands, like this, 123,456,789. Receiving 1 parameter at the same time, you can specify that small float types keep several decimal places:


{{ num | number : 2 }}

9. orderBy sort, the orderBy filter can sort the elements in an array, and receive a parameter to specify the collation. The parameter can be a string, indicating that the attribute name is sorted. It can be a function that defines sorting properties. It can also be an array, indicating that the values of attributes in the array are sorted in turn (if the values compared by item 1 are equal, then compared by item 2).


{{ expression | filter1 | filter2 | ... }}
4

3. Customize filter

Let's first define a filter without parameters. The first example comes from the official documentation of Angular.

We want to check whether the data is true. If it is true, it will be displayed as 1, otherwise, it will be displayed as ", in Unicode,\ u2713- > \ u2718- > So, all we need to do is check whether the data is true, and then convert it into these two special characters for output.


{{ expression | filter1 | filter2 | ... }}
5

Filters can also have parameters, for example, built-in filters can format words, currency or date.

After the filter, the parameters of the filter are separated by colon (:). In the filter, you can get this parameter. If there are multiple parameters, you will continue to separate them by colon (:), so the filter can have multiple parameters.

The following implements a filter that truncates overly long strings.


{{ expression | filter1 | filter2 | ... }}
6

4. Define highlighted filter

We want the search keyword highlighted in the body, which is the first parameter of the filter, and the second parameter is the search keyword, so that our filter will have two parameters.

The principle of highlighting is very simple. Isolate the content that needs to be highlighted with span tag, and add a special class to describe it.


{{ expression | filter1 | filter2 | ... }}
7

$sce, and $log are two services provided by angular, where the $sce service requires the ngSanitize module. For this module, please refer to: angular-ngSanitize Module-$sanitize Service Details

5. Define service objects

Our page may be very complex, we need to enter a keyword in one controller, but we need to use this keyword in multiple controllers for filtering. How to deal with it? Using services can solve this problem.

In Angular, a service is a singleton object, and we can define a service object directly by using factory.


app.factory("notifyService", function(){
  var target = {
    search:"key"
  };

  return target;
});

Where this object needs to be used, it can be obtained by direct injection.

6. Define search Controller

In the search controller, we want the user to provide search keywords. For the convenience of checking, we will show the user's input by the way.


{{ expression | filter1 | filter2 | ... }}
9

Implementation of the controller, we inject the service object directly into the controller and then bind to the current $scope to implement the binding in the current controller.


app.controller("tools", function($scope, notifyService){
  $scope.notify = notifyService;
});

Now, we can enter the search keyword directly, which will be saved to the service object, which can be accessed in various controllers in the current module.

7. Use filter in content Controller

Now that we have filters, we can also get search keywords directly from service objects, and now we can use them together. text is our body content.


    <div ng-controller="search">
      <div ng-bind-html="text | highlight:notify.search">
      </div>
    </div>

Let's look at where highlight and notify. search came from.


app.controller("search", function($scope, $log, notifyService){
  $scope.text = "hello, world. hello, world. hello, world.";
  $scope.notify = notifyService;
})

In order to use the search keywords in the current controller, the key is that the search keywords need to be updated automatically when they change, so we bind the service object to the current $scope, which is referenced by the name notify.

In this way, in complex pages, we may have multiple controllers. In each controller that needs highlighting, we only need to inject service objects, and we can directly obtain the current search keywords. With the use of filters, we can directly realize global highlighting.

8. Summary


Related articles: