Skip to content
Permalink
Browse files

feat(highlight): highlight array of terms instead of just one term (#…

…3154)

Closes #2698
  • Loading branch information...
IAfanasov authored and maxokorokov committed May 28, 2019
1 parent 2bbaaee commit ec8a1296357e7683753a7db254bfe648cc80f5b4
Showing with 48 additions and 12 deletions.
  1. +34 −0 src/typeahead/highlight.spec.ts
  2. +14 −12 src/typeahead/highlight.ts
@@ -123,6 +123,40 @@ describe('ngb-highlight', () => {

expect(highlightHtml(fixture)).toBe('1<span class="my">2</span>3');
});

it('should highlight when term contains array with 1 item', () => {
const fixture = createTestComponent(`<ngb-highlight result="foo bar baz" [term]="['bar']"></ngb-highlight>`);

expect(highlightHtml(fixture)).toBe('foo <span class="ngb-highlight">bar</span> baz');
});

it('should highlight when term contains array with several items', () => {
const fixture = createTestComponent(`<ngb-highlight result="foo bar baz" [term]="['foo', 'baz']"></ngb-highlight>`);

expect(highlightHtml(fixture))
.toBe('<span class="ngb-highlight">foo</span> bar <span class="ngb-highlight">baz</span>');
});

it('should highlight when term contains array with several items and the terms in text stand together', () => {
const fixture = createTestComponent(`<ngb-highlight result="foobar baz" [term]="['foo', 'bar']"></ngb-highlight>`);

expect(highlightHtml(fixture))
.toBe('<span class="ngb-highlight">foo</span><span class="ngb-highlight">bar</span> baz');
});

it('should not fail when term contains null element', () => {
const fixture = createTestComponent(`<ngb-highlight result="foo bar baz" [term]="[null, 'bar']"></ngb-highlight>`);

expect(highlightHtml(fixture)).toBe('foo <span class="ngb-highlight">bar</span> baz');
});

it('should highlight when term contains mix of strings and numbers', () => {
const fixture =
createTestComponent(`<ngb-highlight [result]="1123456789" [term]="[123, 345, '678']"></ngb-highlight>`);

expect(highlightHtml(fixture))
.toBe('1<span class="ngb-highlight">123</span>45<span class="ngb-highlight">678</span>9');
});
});


@@ -30,28 +30,30 @@ export class NgbHighlight implements OnChanges {
* The text highlighting is added to.
*
* If the `term` is found inside this text, it will be highlighted.
* If the `term` contains array then all the items from it will be highlighted inside the text.
*/
@Input() result: string;

/**
* The term to be highlighted.
* The term or array of terms to be highlighted.
*/
@Input() term: string;
@Input() term: string | string[];

ngOnChanges(changes: SimpleChanges) {
const resultStr = toString(this.result);
const resultLC = resultStr.toLowerCase();
const termLC = toString(this.term).toLowerCase();
let currentIdx = 0;
if (!resultStr) {
this.parts = [resultStr];
return;
}
let resultTerms: string[] = Array.isArray(this.term) ? this.term.map(x => toString(x)) : [toString(this.term)];

if (termLC.length > 0) {
this.parts = resultLC.split(new RegExp(`(${regExpEscape(termLC)})`)).map((part) => {
const originalPart = resultStr.substr(currentIdx, part.length);
currentIdx += part.length;
return originalPart;
});
} else {
resultTerms = resultTerms.filter(x => x);
if (!resultTerms.length) {
this.parts = [resultStr];
return;
}

const regexStr = `(${resultTerms.map(x => regExpEscape(x)).join('|')})`;
this.parts = resultStr.split(new RegExp(regexStr, 'gmi'));
}
}

0 comments on commit ec8a129

Please sign in to comment.
You can’t perform that action at this time.