Skip to content

Commit

Permalink
feat(highlight): highlight array of terms instead of just one term (#…
Browse files Browse the repository at this point in the history
…3154)

Closes #2698
  • Loading branch information
IAfanasov authored and maxokorokov committed May 28, 2019
1 parent 2bbaaee commit ec8a129
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 12 deletions.
34 changes: 34 additions & 0 deletions src/typeahead/highlight.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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');
});
});


Expand Down
26 changes: 14 additions & 12 deletions src/typeahead/highlight.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'));
}
}

1 comment on commit ec8a129

@idobleicher
Copy link

@idobleicher idobleicher commented on ec8a129 Jul 20, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice commit! you saved me! thanks

Please sign in to comment.