Reputation: 1569
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>
Upvotes: 0
Views: 2277
Reputation: 4622
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>
Upvotes: 1