0

I have a simple table and every next row is added by clicking "Append" button.

I need to highlight matches between search input field with table input fields.

Trying to use highlight filter to achieve this, but it it runs with an error:

"TypeError: Cannot read property 'replace' of undefined"

How could I fix it? Example code below:

var app = angular.module("myApp",[]);

            app.filter('highlight', function($sce) {
                return function(text, phrase) {
                if (phrase) text = text.replace(new RegExp('('+phrase+')', 'gi'),
                '<span class="highlighted">$1</span>')
                return $sce.trustAsHtml(text)
                }
            });

            app.controller("myCtrl", ['$scope', 'highlightFilter', function($scope, highlightFilter){
                $scope.arr = [];
                $scope.append = function(){
                    var x = {};
                    x.data1 = "";
                    x.data2 = "";
                    $scope.arr.push(x); 
                };
            }]);
<!DOCTYPE html>
<html>
    <head>
        <title>Author's List</title>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.min.js"></script>
        <link href="https://netdna.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
        <style>
            .highlighted { background: yellow }
        </style>
    </head>
    <body ng-controller="myCtrl" ng-app="myApp">
        <div class="container">
            <div class="btn-group">
                <button ng-click ="append()" type="button" class="btn btn-default">Append</button>
                <input type="text" placeholder="Search" ng-model="search.text">
                <ul>
                    <div ng-repeat="x in arr | filter:search.text" ng-bind-html="x.text | highlight:search.text"></div>
                </ul>
            </div>
            <form name ="myForm" novalidate> 
                <table class="table table-bordered">
                    <tr>
                        <th>data1</th>
                        <th>data2</th>
                    </tr>
                    <tr ng-repeat="x in arr">
                        <td><input ng-model="x.data1" required type="text" class="form-control"></td>
                        <td><input ng-model="x.data2" required type="text" class="form-control"></td>
                    </tr>
                </table>
            </form>
        </div>
           </body>
</html>    

1 Answer 1

1

The issue here is that your filter takes input text as first parameter, but you are passing a field that is not defined on your model: ng-bind-html="x.text | highlight:search.text". You have fields data1 and data2 but not text, that is why you are getting the mentioned error.

Your filter is actually working, but you have to pass a proper input parameter into it:

var app = angular.module("myApp",[]);

            app.filter('highlight', function($sce) {
                return function(text, phrase) {
                if (phrase) text = text.replace(new RegExp('('+phrase+')', 'gi'),
                '<span class="highlighted">$1</span>')
                return $sce.trustAsHtml(text)
                }
            });

            app.controller("myCtrl", ['$scope', 'highlightFilter', function($scope, highlightFilter){
                $scope.arr = [];
                $scope.append = function(){
                    var x = {};
                    x.data1 = "";
                    x.data2 = "";
                    $scope.arr.push(x); 
                };
            }]);
<!DOCTYPE html>
<html>
    <head>
        <title>Author's List</title>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.min.js"></script>
        <link href="https://netdna.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
        <style>
            .highlighted { background: yellow }
        </style>
    </head>
    <body ng-controller="myCtrl" ng-app="myApp">
        <div class="container">
            <div class="btn-group">
                <button ng-click ="append()" type="button" class="btn btn-default">Append</button>
                <input type="text" placeholder="Search" ng-model="search.text">
                <br style="clear: both;"/>
                <ul>
                    <li ng-repeat="x in arr | filter:search.text">
                      <span ng-bind-html="x.data1 | highlight:search.text"></span>
                      <span ng-bind-html="x.data2 | highlight:search.text"></span>
                    </li>
                </ul>
            </div>
            <form name ="myForm" novalidate> 
                <table class="table table-bordered">
                    <tr>
                        <th>data1</th>
                        <th>data2</th>
                    </tr>
                    <tr ng-repeat="x in arr">
                        <td><input ng-model="x.data1" required type="text" class="form-control"></td>
                        <td><input ng-model="x.data2" required type="text" class="form-control"></td>
                    </tr>
                </table>
            </form>
        </div>
           </body>

Sign up to request clarification or add additional context in comments.

2 Comments

thanks! any possibility to highlight in inputs directly?
@VladyslavPlakhuta no, since input supports only plain text. The only was is to emulate inputs with div and contenteditable="true". You can see an example here stackoverflow.com/a/44675864/4222181

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.