From 389a19f61f0b90dd211816a9a3d3bf830829900b Mon Sep 17 00:00:00 2001 From: Danny Nguyen Date: Tue, 11 Sep 2018 16:28:42 -0700 Subject: [PATCH] Add option for custom search function --- demo/src/app/dummy.component.html | 5 +++++ demo/src/app/dummy.component.ts | 4 ++++ src/dropdown/dropdown.component.ts | 10 +++++++++- src/dropdown/search-filter.pipe.ts | 14 +++++--------- 4 files changed, 23 insertions(+), 10 deletions(-) diff --git a/demo/src/app/dummy.component.html b/demo/src/app/dummy.component.html index 4873b403..7862a6d8 100644 --- a/demo/src/app/dummy.component.html +++ b/demo/src/app/dummy.component.html @@ -10,4 +10,9 @@

Dropdown Demo

With search and buttons:

+ +

+ With custom prefix search and buttons: + +

diff --git a/demo/src/app/dummy.component.ts b/demo/src/app/dummy.component.ts index 86ba1131..dc311eac 100644 --- a/demo/src/app/dummy.component.ts +++ b/demo/src/app/dummy.component.ts @@ -17,4 +17,8 @@ export class DummyComponent { showCheckAll: true, showUncheckAll: true }; + + prefixSearchFunction(str: string): RegExp { + return new RegExp('^' + str, 'i'); + } } diff --git a/src/dropdown/dropdown.component.ts b/src/dropdown/dropdown.component.ts index 2508766e..3993b53c 100644 --- a/src/dropdown/dropdown.component.ts +++ b/src/dropdown/dropdown.component.ts @@ -64,6 +64,7 @@ export class MultiselectDropdownComponent @Input() texts: IMultiSelectTexts; @Input() disabled: boolean = false; @Input() disabledSelection: boolean = false; + @Input() searchFunction: (str: string) => RegExp = this._escapeRegExp; @Output() selectionLimitReached = new EventEmitter(); @Output() dropdownClosed = new EventEmitter(); @@ -277,7 +278,8 @@ export class MultiselectDropdownComponent options, value, this.settings.searchMaxLimit, - this.settings.searchMaxRenderedItems + this.settings.searchMaxRenderedItems, + this.searchFunction ); } @@ -709,4 +711,10 @@ export class MultiselectDropdownComponent e.stopPropagation(); } } + + private _escapeRegExp(str: string): RegExp { + const regExpStr = str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); + return new RegExp(regExpStr, 'i'); + } + } diff --git a/src/dropdown/search-filter.pipe.ts b/src/dropdown/search-filter.pipe.ts index bf5fd2b6..5dcd6bad 100644 --- a/src/dropdown/search-filter.pipe.ts +++ b/src/dropdown/search-filter.pipe.ts @@ -20,7 +20,8 @@ export class MultiSelectSearchFilter implements PipeTransform { options: IMultiSelectOption[], str = '', limit = 0, - renderLimit = 0 + renderLimit = 0, + searchFunction: (str: string) => RegExp, ): IMultiSelectOption[] { str = str.toLowerCase(); @@ -34,7 +35,7 @@ export class MultiSelectSearchFilter implements PipeTransform { const filteredOpts = this._searchCache.hasOwnProperty(str) ? this._searchCache[str] - : this._doSearch(options, str, limit); + : this._doSearch(options, str, limit, searchFunction); const isUnderLimit = options.length <= limit; @@ -61,7 +62,7 @@ export class MultiSelectSearchFilter implements PipeTransform { return options; } - private _doSearch(options: IMultiSelectOption[], str: string, limit: number) { + private _doSearch(options: IMultiSelectOption[], str: string, limit: number, searchFunction: (str: string) => RegExp) { const prevStr = str.slice(0, -1); const prevResults = this._searchCache[prevStr]; const prevResultShift = this._prevSkippedItems[prevStr] || 0; @@ -72,7 +73,7 @@ export class MultiSelectSearchFilter implements PipeTransform { const optsLength = options.length; const maxFound = limit > 0 ? Math.min(limit, optsLength) : optsLength; - const regexp = new RegExp(this._escapeRegExp(str), 'i'); + const regexp = searchFunction(str); const filteredOpts: IMultiSelectOption[] = []; let i = 0, founded = 0, removedFromPrevResult = 0; @@ -127,9 +128,4 @@ export class MultiSelectSearchFilter implements PipeTransform { private _limitRenderedItems(items: T[], limit: number): T[] { return items.length > limit && limit > 0 ? items.slice(0, limit) : items; } - - private _escapeRegExp(str: string): string { - return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); - } - }