Hala El Barchah Hala El Barchah - 3 months ago 17
AngularJS Question

Skip HTML tags to add highlight to content only, not to HTML tags

I want to replace HTML template content with new one after highlighting the words those match the search input.

As shown in the snippet, I am using

highlight
filter that adds yellow background to matched words by adding
&zwj;<span class="highlighted">$1&zwj;</span>
.

The problem is that sometimes this
<span>
is added inside HTML tags if there is matched string in it. for example: In the HTML, there is tag
<md-icon class="material-icons">error_outline</md-icon>
. if the search string is
ma
, then the tag will become
<md-icon class="&zwj;<span class="highlighted">ma&zwj;</span>terial-icons">error_outline</md-icon>
.

How can I skip HTML tags, so the highlighting will be applied to the content only, not to HTML tags?

Try to input
m
, and you can see some HTML tags appear, like
<module>


PS: if possible, is there is a way to skip
error_outline
also in case of
<md-icon class="material-icons">error_outline</md-icon>
, because it's referred to material icons.



angular.module("myApp", ["ngMaterial"])
.filter('highlight', function ($sce) {
return function (text, searchSrting) {
if(searchSrting){
searchSrting = searchSrting.split(/\s+/);
if(typeof text !== "undefined")
for (var i = 0; i < searchSrting.length; i++) {
text = text.replace(new RegExp('(' + searchSrting[i] + ')', 'gi'),
'<span class="highlighted">$1</span>')
}
return $sce.trustAsHtml(text)
}
}
})
.controller("main", function($scope){
$scope.searchString="";
$scope.content="<module> <ti-tle>User Management</ti-tle><br><tag-group><tag>User Management</tag></tag-group><info-group><info><md-icon class='material-icons ltr'>perm_identity</md-icon>published by: Ha ba</info> <info><md-icon class='material-icons ltr'>folder</md-icon>User Management</info><info><md-icon class='material-icons ltr'>publish</md-icon>published: 25 May 2016</info></info-group><hr>In <bold>AMe</bold>, you can manage multiple bank accounts <br><br> <sub-title> Introduction </sub-title> The Sales Planner is a useful step-by-step guide created to help you implement your sales funnel <br> Go to <bold>Accounting</bold> ‣ <bold>Configuration</bold> ‣ <bold>Bank Accounts</bold> and click on the Bank item. Edit it <note><md-icon class='material-icons'>error_outline</md-icon> AMeSCom will detect the bank account type (e.g. IBAN) to allow some payment method like SEPA. </note> <br><br> <sub-title> Set up your first sales team </sub-title> For example, if within your company Tim is selling products and John is selling maintenance contracts, they will be assigned to different teams and will only receive opportunities that make sense to them. <br><br> <sub-title> Set up incoming email to generate opportunities </sub-title> In Odoo CRM, one way to generate opportunities into your sales team is to create a generic email address as a trigger. </module>";
})

module{
font-size: 14px;
color: #484848;
}
ti-tle {
font-size: x-large;
color: rgb(50, 118, 177);
display: block;
font-weight: bold;
}
tag-group{
display: block;
line-height: 3;
}
tag{
background-color: #daebe8;
padding:2px 6px;
font-weight: bold;
font-size: 12px;
margin: 2px;
border-radius: 4px;
cursor: pointer;
color: #667292;
}
tag:hover{
background-color: #87bdd8;
}
info-group{display: block}
info{
color: gray;
margin: 4px;
font-size: 12px;
}
sub-title{
font-weight: bold;
font-size: 18px;
display: block;
line-height: 2;
}
img{
display: block;
margin: 30px 0;
width: 100%;
}
bold{
font-weight: bold;
}
note{
background-color: antiquewhite;
}
.highlighted {
background: yellow;
}
md-icon{direction: ltr}

<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.7/angular.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.7/angular-animate.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.7/angular-aria.js"></script>
<script src="//rawgit.com/angular/bower-material/master/angular-material.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/angular-material/1.3.7/angular-material.css"/>

<div ng-app="myApp">
<div ng-controller="main">
<label>search</label>
<input ng-model="searchString"/>
<div ng-if="!searchString">
<module>
<ti-tle>User Management</ti-tle>
<br>
<tag-group>
<tag>User Management</tag>
</tag-group>
<info-group>
<info><md-icon class="material-icons ltr">perm_identity</md-icon>published by: Ha ba</info>
<info><md-icon class="material-icons ltr">folder</md-icon>User Management</info>
<info><md-icon class="material-icons ltr">publish</md-icon>published: 25 May 2016</info>
</info-group>
<hr>

In <bold>AMe</bold>, you can manage multiple bank accounts
<br><br>
<sub-title>
Introduction
</sub-title>
The Sales Planner is a useful step-by-step guide created to help you implement your sales funnel
<br>
Go to <bold>Accounting</bold> ‣ <bold>Configuration</bold> ‣ <bold>Bank Accounts</bold> and click on the Bank item. Edit it
<note><md-icon class="material-icons">error_outline</md-icon>
AMeSCom will detect the bank account type (e.g. IBAN) to allow some payment method like SEPA.
</note>
<br><br>
<sub-title>
Set up your first sales team
</sub-title>
For example, if within your company Tim is selling products and John is selling maintenance contracts, they will be assigned to different teams and will only receive opportunities that make sense to them.


<br><br>
<sub-title>
Set up incoming email to generate opportunities
</sub-title>
In Odoo CRM, one way to generate opportunities into your sales team is to create a generic email address as a trigger. For example, if
</module>


</div>
<div ng-if="searchString" ng-bind-html="content | highlight:searchString"></div>

</div>
</div>




Answer

I have edited my answer because of some mistake

var text = "<div>some text <span class='text'> some text</span> to</div>";
var tag = 'text';
var tagvalue = "here is result";

function mapText(text,tag,tagValue){
  var reg = new RegExp("[\>][^\<\>.]*"+tag+"[^\<\>.]*[\<]","gi");
  var result = text.replace(reg,function(item,exp){
    var subRegex = new RegExp(tag,"gi");
    return item.replace(subRegex,tagValue);
  });
  return result;
};
mapText(text,tag,tagvalue)