Skip to content

Commit bdff4ab

Browse files
committed
feat: added support for search on keys array and json path #297
1 parent 0f7ffc5 commit bdff4ab

File tree

6 files changed

+46
-16
lines changed

6 files changed

+46
-16
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
* search dropdown list
1717
* arrows keys support
1818
* limit number of items displayed in dropdown
19-
* custom sort
19+
* custom sort
2020
* angular forms support
2121
* angular v4 and above supported
2222
* cross browser support
@@ -105,7 +105,7 @@ config = {
105105
moreText: 'more' // text to be displayed whenmore than one items are selected like Option 1 + 5 more
106106
noResultsFound: 'No results found!' // text to be displayed when no items are found while searching
107107
searchPlaceholder:'Search' // label thats displayed in search input,
108-
searchOnKey: 'name' // key on which search should be performed this will be selective search. if undefined this will be extensive search on all keys
108+
searchOnKey: 'name' // key or array of keys on which search should be performed this will be selective search. if undefined this will be extensive search on all keys, you may also provide an object path (array objects are not supported)
109109
clearOnSelection: false // clears search criteria when an option is selected if set to true, default is false
110110
inputDirection: 'ltr' // the direction of the search input can be rtl or ltr(default)
111111
selectAllLabel: 'Select all' // label that is displayed in multiple selection for select all

projects/demo/src/app/app.component.html

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -119,17 +119,17 @@ <h6>Input</h6>
119119
moreText: 'more' // text to be displayed whenmore than one items are selected like Option 1 + 5 more
120120
noResultsFound: 'No results found!' // text to be displayed when no items are found while searching
121121
searchPlaceholder:'Search' // label thats displayed in search input,
122-
searchOnKey: 'name' // key on which search should be performed this will be selective search. if undefined this will be extensive search on all keys
122+
searchOnKey: 'name' // key or array of keys on which search should be performed this will be selective search. if undefined this will be extensive search on all keys, you may also provide an object path (array objects are not supported)
123123
{{ '}' }}</pre>
124124
<ul>
125125
<li>
126-
<strong>selectedItemTemplate: TemplateRef</strong> - a template reference for the selectedItems
126+
<strong>selectedItemTemplate: TemplateRef</strong> - a template reference for the selectedItems
127127
</li>
128128
<li>
129-
<strong>optionItemTemplate: TemplateRef</strong> - a template reference for the available options
129+
<strong>optionItemTemplate: TemplateRef</strong> - a template reference for the available options
130130
</li>
131131
<li>
132-
<strong>notFoundTemplate: TemplateRef</strong> - a template reference in case no matching items for search
132+
<strong>notFoundTemplate: TemplateRef</strong> - a template reference in case no matching items for search
133133
</li>
134134
<li>
135135
<strong>dropdownButtonTemplate: TemplateRef</strong> - a template reference for the dropdown action button
@@ -143,7 +143,7 @@ <h6>Input</h6>
143143
&lt;span&gt; class="new badge"&gt; &lt;/span&gt;
144144
&lt;/ng-template&gt;
145145

146-
&lt;ngx-select-dropdown&gt; [optionItemTemplate]="optionTemplate"
146+
&lt;ngx-select-dropdown&gt; [optionItemTemplate]="optionTemplate"
147147
[selectedItemTemplate]="optionTemplate"
148148
tabindex="0" [multiple]="true" [(ngModel)]="optTemplate" [options]="options"
149149
[config]="config">&lt;/ngx-select-dropdown&gt;</strong>

projects/ngx-select-dropdown/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
* search dropdown list
1717
* arrows keys support
1818
* limit number of items displayed in dropdown
19-
* custom sort
19+
* custom sort
2020
* angular forms support
2121
* angular v4 and above supported
2222
* cross browser support
@@ -105,7 +105,7 @@ config = {
105105
moreText: 'more' // text to be displayed whenmore than one items are selected like Option 1 + 5 more
106106
noResultsFound: 'No results found!' // text to be displayed when no items are found while searching
107107
searchPlaceholder:'Search' // label thats displayed in search input,
108-
searchOnKey: 'name' // key on which search should be performed this will be selective search. if undefined this will be extensive search on all keys
108+
searchOnKey: 'name' // key or array of keys on which search should be performed this will be selective search. if undefined this will be extensive search on all keys, you may also provide an object path (array objects are not supported)
109109
clearOnSelection: false // clears search criteria when an option is selected if set to true, default is false
110110
inputDirection: 'ltr' // the direction of the search input can be rtl or ltr(default)
111111
selectAllLabel: 'Select all' // label that is displayed in multiple selection for select all

projects/ngx-select-dropdown/src/lib/pipes/filter-by.pipe.spec.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,11 @@ const testData = [
4343
email: 'holmes.ratliff@aclima.co.uk',
4444
phone: '+1 (977) 541-2880',
4545
address: '736 Dikeman Street, Vallonia, Wyoming, 1370',
46-
about: 'Reprehenderit et sint eu sunt occaecat sint dolore minim aliqua aute enim incididunt. Labore officia qui proident esse cupidatat sint deserunt. Velit qui incididunt ullamco ullamco qui. Nostrud in sit laboris sit pariatur esse ea dolore elit enim.'
46+
about: 'Reprehenderit et sint eu sunt occaecat sint dolore minim aliqua aute enim incididunt. Labore officia qui proident esse cupidatat sint deserunt. Velit qui incididunt ullamco ullamco qui. Nostrud in sit laboris sit pariatur esse ea dolore elit enim.',
47+
otherDetails: {
48+
firstName: 'Tea',
49+
lastName: 'Pot'
50+
}
4751
},
4852
{
4953
_id: '5ab9c820ad13b4f8707133e7',
@@ -154,4 +158,9 @@ describe('FilterByPipe', () => {
154158
const arr = ['star', 'galaxy', 'sun', 'moon', 'earth'];
155159
expect(pipe.transform(arr, 'ar')).toEqual(['star', 'earth']);
156160
});
161+
162+
it('should return the filtered array of objects', () => {
163+
const pipe = new FilterByPipe();
164+
expect(pipe.transform(testData, 'Tea', ['firstName', 'otherDetails.firstName'])).toEqual([testData[2]]);
165+
});
157166
});

projects/ngx-select-dropdown/src/lib/pipes/filter-by.pipe.ts

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,28 +7,49 @@ import { Pipe, PipeTransform } from '@angular/core';
77
name: 'filterBy'
88
})
99
export class FilterByPipe implements PipeTransform {
10-
public transform(array: any[], searchText?: string, keyName?: string) {
10+
private getValueByPath(obj: any, path: string): any {
11+
if (!path) return obj;
12+
13+
return path.split('.').reduce((acc, part) => acc && acc[part], obj);
14+
}
15+
16+
private predicate(value: any, searchText: string): boolean {
17+
return typeof value !== 'object' && typeof value !== 'undefined' && value !== null && value.toString().toLowerCase().indexOf(searchText.trim().toLowerCase()) > -1
18+
}
19+
20+
public transform(array: any[], searchText?: string, keyName?: string | string[]) {
1121
if (!array || !searchText || !Array.isArray(array)) {
1222
return array;
1323
}
1424
if (typeof array[0] === 'string') {
15-
return array.filter((item) => item.toLowerCase().indexOf(searchText.trim().toLowerCase()) > -1);
25+
return array.filter((item) => this.predicate(item, searchText));
1626
}
1727
// filter array, items which match and return true will be
1828
// kept, false will be filtered out
1929
if (!keyName) {
2030
return array.filter((item: any) => {
2131
for (const key in item) {
22-
if (typeof item[key] !== 'object' && item[key].toString().toLowerCase().indexOf(searchText.trim().toLowerCase()) > -1) {
32+
const value = this.getValueByPath(item, key);
33+
if (this.predicate(value, searchText)) {
2334
return true;
2435
}
2536
}
2637
return false;
2738
});
2839
} else {
2940
return array.filter((item: any) => {
30-
if (typeof item[keyName] !== 'object' && item[keyName].toString().toLowerCase().indexOf(searchText.trim().toLowerCase()) > -1) {
31-
return true;
41+
if (typeof keyName === 'string') {
42+
const value = this.getValueByPath(item, keyName);
43+
if (this.predicate(value, searchText)) {
44+
return true;
45+
}
46+
} else {
47+
for (const key of keyName) {
48+
const value = this.getValueByPath(item, key);
49+
if (this.predicate(value, searchText)) {
50+
return true;
51+
}
52+
}
3253
}
3354
return false;
3455
});

projects/ngx-select-dropdown/src/lib/types/ngx-select-dropdown.types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export interface NgxDropdownConfig {
99
moreText?: string;
1010
noResultsFound?: string;
1111
searchPlaceholder?: string;
12-
searchOnKey?: string;
12+
searchOnKey?: string | string[];
1313
clearOnSelection?: boolean;
1414
inputDirection?: string;
1515
selectAllLabel?: string;

0 commit comments

Comments
 (0)