Skip to content

Commit d80bdfd

Browse files
feat(typeahead): add sort functionality to typeahead (#5646)
Add sort functionality to typeahead Close #4808 Co-authored-by: Dmitriy Danilov <daniloff200@gmail.com>
1 parent 2c36e33 commit d80bdfd

File tree

10 files changed

+486
-49
lines changed

10 files changed

+486
-49
lines changed

demo/src/app/components/+typeahead/demos/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import { DemoTypeaheadScrollableComponent } from './scrollable/scrollable';
2323
import { DemotypeaheadSelectFirstItemComponent } from './selected-first-item/selected-first-item';
2424
import { DemoTypeaheadShowOnBlurComponent } from './show-on-blur/show-on-blur';
2525
import { DemoTypeaheadSingleWorldComponent } from './single-world/single-world';
26+
import { DemoTypeaheadOrderingComponent } from './ordering/ordering';
2627

2728
export const DEMO_COMPONENTS = [
2829
DemoTypeaheadAdaptivePositionComponent,
@@ -51,5 +52,6 @@ export const DEMO_COMPONENTS = [
5152
DemoTypeaheadScrollableComponent,
5253
DemotypeaheadSelectFirstItemComponent,
5354
DemoTypeaheadShowOnBlurComponent,
54-
DemoTypeaheadSingleWorldComponent
55+
DemoTypeaheadSingleWorldComponent,
56+
DemoTypeaheadOrderingComponent
5557
];
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<div class="mb-3">
2+
<h6>Source - <strong>array of string</strong>. Order direction - <strong>descending</strong></h6>
3+
<input [(ngModel)]="selected1"
4+
[typeahead]="states"
5+
[typeaheadOrderBy]="sortConfig1"
6+
class="form-control">
7+
</div>
8+
<div class="mb-3">
9+
<h6>Source - <strong>array of string</strong>. Order direction - <strong>ascending</strong></h6>
10+
<input [(ngModel)]="selected2"
11+
[typeahead]="states"
12+
[typeaheadOrderBy]="sortConfig2"
13+
class="form-control">
14+
</div>
15+
<div class="mb-3">
16+
<h6>
17+
Source - <strong>array of objects</strong>. Order direction - <strong>ascending</strong>,
18+
sort by <strong>city</strong>, group by <strong>state</strong>
19+
</h6>
20+
<input [(ngModel)]="selected3"
21+
[typeahead]="cities"
22+
typeaheadOptionField="city"
23+
typeaheadGroupField="state"
24+
[typeaheadItemTemplate]="customItemTemplate"
25+
[typeaheadOrderBy]="sortConfig3"
26+
class="form-control">
27+
28+
<ng-template #customItemTemplate let-model="item">
29+
<span><strong>{{model.city}}</strong> - {{model.code}}</span>
30+
</ng-template>
31+
</div>
32+
33+
<div class="mb-3">
34+
<h6>Source - <strong>Observable of array of string</strong>. Order direction - <strong>descending</strong></h6>
35+
<input [(ngModel)]="selected4"
36+
[typeahead]="states$"
37+
[typeaheadAsync]="true"
38+
[typeaheadOrderBy]="sortConfig1"
39+
class="form-control">
40+
</div>
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
import { Component, OnInit } from '@angular/core';
2+
3+
import { TypeaheadOrder } from 'ngx-bootstrap/typeahead';
4+
import { Observable, of, Subscriber } from 'rxjs';
5+
import { switchMap } from 'rxjs/operators';
6+
7+
@Component({
8+
selector: 'demo-typeahead-ordering',
9+
templateUrl: './ordering.html'
10+
})
11+
export class DemoTypeaheadOrderingComponent implements OnInit {
12+
selected1: string;
13+
selected2: string;
14+
selected3: string;
15+
selected4: string;
16+
sortConfig1: TypeaheadOrder = {
17+
direction: 'desc'
18+
};
19+
sortConfig2: TypeaheadOrder = {
20+
direction: 'asc'
21+
};
22+
sortConfig3: TypeaheadOrder = {
23+
direction: 'asc',
24+
field: 'city'
25+
};
26+
states$: Observable<string[]>;
27+
states: string[] = [
28+
'New Mexico',
29+
'New York',
30+
'North Dakota',
31+
'North Carolina',
32+
'Ohio',
33+
'Oklahoma',
34+
'Oregon',
35+
'Pennsylvania',
36+
'Rhode Island',
37+
'South Carolina',
38+
'South Dakota',
39+
'Tennessee',
40+
'Texas',
41+
'Utah',
42+
'Alaska',
43+
'Alabama',
44+
'Iowa',
45+
'Kansas',
46+
'Kentucky',
47+
'Louisiana',
48+
'Maine',
49+
'Maryland',
50+
'Massachusetts',
51+
'Michigan',
52+
'Minnesota',
53+
'Mississippi',
54+
'Missouri',
55+
'Montana',
56+
'Nebraska',
57+
'Nevada',
58+
'New Hampshire',
59+
'New Jersey',
60+
'Arizona',
61+
'Arkansas',
62+
'California',
63+
'Colorado',
64+
'Connecticut',
65+
'Delaware',
66+
'Florida',
67+
'Georgia',
68+
'Hawaii',
69+
'Idaho',
70+
'Illinois',
71+
'Indiana',
72+
'Vermont',
73+
'Virginia',
74+
'Washington',
75+
'West Virginia',
76+
'Wisconsin',
77+
'Wyoming'
78+
];
79+
cities = [{
80+
city: 'Norton',
81+
state: 'Virginia',
82+
code: '61523'
83+
}, {
84+
city: 'Grundy',
85+
state: 'Virginia',
86+
code: '77054'
87+
}, {
88+
city: 'Coeburn',
89+
state: 'Virginia',
90+
code: '01665'
91+
}, {
92+
city: 'Phoenix',
93+
state: 'Arizona',
94+
code: '29128'
95+
}, {
96+
city: 'Tucson',
97+
state: 'Arizona',
98+
code: '32084'
99+
}, {
100+
city: 'Mesa',
101+
state: 'Arizona',
102+
code: '21465'
103+
}, {
104+
city: 'Independence',
105+
state: 'Missouri',
106+
code: '26887'
107+
}, {
108+
city: 'Kansas City',
109+
state: 'Missouri',
110+
code: '79286'
111+
}, {
112+
city: 'Springfield',
113+
state: 'Missouri',
114+
code: '92325'
115+
}, {
116+
city: 'St. Louis',
117+
state: 'Missouri',
118+
code: '64891'
119+
}];
120+
121+
ngOnInit(): void {
122+
this.states$ = new Observable((observer: Subscriber<string>) => {
123+
// Runs on every search
124+
observer.next(this.selected4);
125+
})
126+
.pipe(
127+
switchMap((token: string) => {
128+
const query = new RegExp(token, 'i');
129+
130+
return of(
131+
this.states.filter((state: string) => query.test(state))
132+
);
133+
})
134+
);
135+
}
136+
}

demo/src/app/components/+typeahead/typeahead-section.list.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import { ExamplesComponent } from '../../docs/demo-section-components/demo-examp
2929

3030
import { NgApiDocComponent, NgApiDocConfigComponent } from '../../docs/api-docs';
3131
import { DemoTypeaheadFirstItemActiveComponent } from './demos/first-item-active/first-item-active';
32+
import { DemoTypeaheadOrderingComponent } from './demos/ordering/ordering';
3233

3334
export const demoComponentContent: ContentSection[] = [
3435
{
@@ -275,6 +276,16 @@ export const demoComponentContent: ContentSection[] = [
275276
component: require('!!raw-loader!./demos/selected-first-item/selected-first-item.ts'),
276277
html: require('!!raw-loader!./demos/selected-first-item/selected-first-item.html'),
277278
outlet: DemotypeaheadSelectFirstItemComponent
279+
},
280+
{
281+
title: 'Order results',
282+
anchor: 'typeahead-ordering',
283+
description: `
284+
<p>Use <code>typeaheadOrderBy</code> property to order your result by a certain field and in certain direction</p>
285+
`,
286+
component: require('!!raw-loader!./demos/ordering/ordering.ts'),
287+
html: require('!!raw-loader!./demos/ordering/ordering.html'),
288+
outlet: DemoTypeaheadOrderingComponent
278289
}
279290
]
280291
},

demo/src/ng-api-doc.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2332,6 +2332,16 @@ export const ngdoc: any = {
23322332
"type": "boolean",
23332333
"description": "<p>Toggle animation</p>\n"
23342334
},
2335+
{
2336+
"name": "ariaDescribedby",
2337+
"type": "string",
2338+
"description": "<p>aria-describedby attribute value to set on the modal window</p>\n"
2339+
},
2340+
{
2341+
"name": "ariaLabelledBy",
2342+
"type": "string",
2343+
"description": "<p>aria-labelledby attribute value to set on the modal window</p>\n"
2344+
},
23352345
{
23362346
"name": "backdrop",
23372347
"type": "boolean | \"static\"",
@@ -3915,6 +3925,11 @@ export const ngdoc: any = {
39153925
"type": "number",
39163926
"description": "<p>maximum length of options items list. The default value is 20</p>\n"
39173927
},
3928+
{
3929+
"name": "typeaheadOrderBy",
3930+
"type": "TypeaheadOrder",
3931+
"description": "<p>Used to specify a custom order of matches. When options source is an array of objects\na field for sorting has to be set up. In case of options source is an array of string,\na field for sorting is absent. The ordering direction could be changed to ascending or descending.</p>\n"
3932+
},
39183933
{
39193934
"name": "typeaheadPhraseDelimiters",
39203935
"defaultValue": "'\"",

src/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,8 @@ export {
141141
TypeaheadContainerComponent,
142142
TypeaheadDirective,
143143
TypeaheadMatch,
144-
TypeaheadModule
144+
TypeaheadModule,
145+
TypeaheadOrder
145146
} from './typeahead/index';
146147

147148
export {

0 commit comments

Comments
 (0)