-
-
Save adamrecsko/0f28f474eca63e0279455476cc11eca7 to your computer and use it in GitHub Desktop.
import {PipeTransform, Pipe} from 'angular2/core'; | |
@Pipe({ name: 'highlight' }) | |
export class HighLightPipe implements PipeTransform { | |
transform(text: string, [search]): string { | |
return search ? text.replace(new RegExp(search, 'i'), `<span class="highlight">${search}</span>`) : text; | |
} | |
} | |
/** Usage: | |
* <input type="text" [(ngModel)]="filter"> | |
* <div [innerHTML]="myAwesomeText | highlight : filter"></div> | |
* | |
*/ | |
Hi Its working properly.
what ever the user enters in the input-field getting displayed with highlighted.
How to highlight the search text on plain html page. I tried with below code
My html page:-
<input type="text" [(ngModel)]="search">
<div [innerHTML]="data | highlight: search">
</div>
---------------------------------------------------------------------------------------------------
highlight.component.ts
import { PipeTransform, Pipe } from '@angular/core';
@pipe({ name: 'highlight' })
export class HighlightPipe implements PipeTransform {
transform(text: string, search, content): string {
console.log("search value here!! "+ search);
let pattern = search.replace(/[-[]/{}()*+?.\^$|]/g, '\$&');
pattern = pattern.split(' ').filter((t) => {
return t.length > 0;
}).join('|');
const regex = new RegExp(pattern, 'gi');
return search.replace(regex, (match) => <span class="highlight">${match}</span>
);
}
}
Thanks!
how can i do it without splitting the text to two parts, i need the matched pattern get the style in it's same position of the original text
Below is the implementation which enables you to do a little more things:
- Highlight single match, global match, single match which starts with search string.
- Make the matching case sensitive.
- Pass a highlighting style class.
Implementation:
import {Pipe, PipeTransform} from "@angular/core";
import {SafeHtml} from "@angular/platform-browser";
@pipe({ name: "highlightText" })
export class HighlightPipe implements PipeTransform {
/* use this for single match search */
static SINGLE_MATCH:string = "Single-Match";
/* use this for single match search with a restriction that target should start with search string */
static SINGLE_AND_STARTS_WITH_MATCH:string = "Single-And-StartsWith-Match";
/* use this for global search */
static MULTI_MATCH:string = "Multi-Match";
constructor() {
}
transform(data: string,
highlightText: string,
option:string = "Single-And-StartsWith-Match",
caseSensitive:boolean = false,
highlightStyleName:string = "search-highlight"): SafeHtml {
if (highlightText && data && option) {
let regex:any = "";
let caseFlag:string = !caseSensitive ? "i" : "";
switch (option) {
case "Single-Match": {
regex = new RegExp(highlightText, caseFlag);
break;
}
case "Single-And-StartsWith-Match": {
regex = new RegExp("^" + highlightText, caseFlag);
break;
}
case "Multi-Match": {
regex = new RegExp(highlightText, "g" + caseFlag);
break;
}
default: {
// default will be a global case-insensitive match
regex = new RegExp(highlightText, "gi");
}
}
return data.replace(regex, (match) => `<span class="${highlightStyleName}">${match}</span>`);
} else {
return data;
}
}
}
Great, but how can I add an event click to this highlighted text after it is rendered into innerhtml?
this regex pattern mean what? thanks
This code is not quite correct. For example:
input - xaxa
users: [ 'xaxalololo', 'nonoxaxaxaxa', 'wtfxaxaxaxaxaxa' ]
Should works only to first occurrence, the code below is correct:
const regex = new RegExp(`${pattern}(.*?)`, 'i');
After that:
users: [ 'xaxalololo', 'nonoxaxaxaxa', 'wtfxaxaxaxaxaxa' ]
In case someone is having problems with @ankitgrover 's code (Thank you!) :
import { Pipe, PipeTransform } from "@angular/core";
import { SafeHtml } from "@angular/platform-browser";
@Pipe({ name: "highlightText" })
export class HighlightPipe implements PipeTransform {
/* use this for single match search */
static SINGLE_MATCH: string = "Single-Match";
/* use this for single match search with a restriction that target should start with search string */
static SINGLE_AND_STARTS_WITH_MATCH: string = "Single-And-StartsWith-Match";
/* use this for global search */
static MULTI_MATCH: string = "Multi-Match";
constructor() {}
transform(
contentString: string = null,
stringToHighlight: string = null,
option: string = "Single-And-StartsWith-Match",
caseSensitive: boolean = false,
highlightStyleName: string = "search-highlight"
): SafeHtml {
if (stringToHighlight && contentString && option) {
let regex: any = "";
let caseFlag: string = !caseSensitive ? "i" : "";
switch (option) {
case "Single-Match": {
regex = new RegExp(stringToHighlight, caseFlag);
break;
}
case "Single-And-StartsWith-Match": {
regex = new RegExp("^" + stringToHighlight, caseFlag);
break;
}
case "Multi-Match": {
regex = new RegExp(stringToHighlight, "g" + caseFlag);
break;
}
default: {
// default will be a global case-insensitive match
regex = new RegExp(stringToHighlight, "gi");
}
}
const replaced = contentString.replace(
regex,
(match) => `<span class="${highlightStyleName}">${match}</span>`
);
return replaced;
} else {
return contentString;
}
}
}
Usage:
<div [innerHTML]="
string
| highlightText
: string
: 'string'
: boolean
: 'string'
"></div>
<td>
<div [innerHTML]="
row.content
| highlightText
: searchInputValue
: 'MULTI_MATCH'
: true
: 'your-class'
"></div>
</td>
@rafcontreras use this, so you can search for special characters too:
stringToHighlight = stringToHighlight.replace(/([-[\]{}()*+?.\\^$|#,])/g,'\\$1');
Perfect! Thank you! 👍