SearchBox, infinite Scroll and Mobile View are embedded into Angular Material Select Component.
This library was generated for Angular Material to improve select component (mat-select). In this library, I defined a
directive for which generate Search box and Mobile View.
Extra Features, after use this directive:
- Searchable (Client Side And Server Side)
- Mobile View in two ways ('FullScreen' | 'BottomSheet')
RLT support (use dir='rtl' in html tag)
Compatible with Angular SSR (Universal)
The first step is adding ngx-mat-select.styles in angular.json
"styles": [
"./node_modules/ngx-mat-select/styles/ngx-mat-select.styles.css"
],
The second step is adding NgxMatSelectModule into your Module
import {MatSelectModule} from "@angular/material/select";
import {NgxMatSelectModule} from "ngx-mat-select";
...
@NgModule({
imports: [
...
MatSelectModule,
NgxMatSelectModule
...
]
})
you can define global default configs for root:
NgxMatSelectModule.forRoot({
maxWidthForMobileView: 600,
inFirstLoadCallSearcher: true,
inFirstLoadSearcherValue: '',
emptyLabel: 'no entry found',
noMoreResultLabel: 'no more found',
useInfiniteScroll: false,
searchBoxPlaceholder: 'please search',
maximumResultForShow: 40,
useMobileView: false,
valueMember: 'key',
displayMember: 'value',
mobileViewType: 'FullScreen'
})
or using token (NGX_MAT_SELECT_CONFIGS) in providers:
providers: [
{provide: NGX_MAT_SELECT_CONFIGS, useValue: ngxMatSelectConfigs}
],
Client Side Search (BottomSheet View In Mobile)
Template:
<mat-form-field>
<mat-select
ngxMatSelect
[hasSearchBox]="true"
[useMobileView]="true"
mobileViewType="BottomSheet"
[(ngModel)]="bankValue"
[multiple]="false"
name="bank"
[required]="true"
[source]="source"
[displayMember]="'value'"
[valueMember]="'key'"
#sf="ngxMatSelect"
>
<mat-option [value]="option" *ngFor="let option of sf.filteredSource">
{{option.value}}
</mat-option>
</mat-select>
</mat-form-field>
component.ts:
export class MyComponent implements OnInit {
bankValue = {key: 50, value: 'Bank_50'};
source: any[] = [];
ngOnInit(): void {
for (let i = 0; i < 100; i++) {
this.source.push({value: 'Bank_' + i, key: i})
}
}
}
Client Side Search ( FullScreen View In Mobile)
Template:
<mat-form-field>
<mat-select
ngxMatSelect
[hasSearchBox]="true"
[useMobileView]="true"
mobileViewType="FullScreen"
[(ngModel)]="bankValue"
[multiple]="true"
name="bank"
[required]="true"
[source]="source"
[displayMember]="'value'"
[valueMember]="'key'"
#sf="ngxMatSelect"
>
<mat-option [value]="option" *ngFor="let option of sf.filteredSource">
{{option.value}}
</mat-option>
</mat-select>
</mat-form-field>
component.ts:
export class MyComponent implements OnInit {
bankValue = [{key: 10, value: 'Bank_10'},{key: 75, value: 'Bank_75'}];
source: any[] = [];
ngOnInit(): void {
for (let i = 0; i < 100; i++) {
this.source.push({value: 'Bank_' + i, key: i})
}
}
}
Server Side Search Template:
<mat-form-field>
<mat-select
ngxMatSelect
[lazyLoad]="true"
[searcher]="bankSearcher.bind(this)"
[hasSearchBox]="true"
[useMobileView]="true"
mobileViewType="FullScreen"
[(ngModel)]="bankValue"
[multiple]="true"
name="bank"
[required]="true"
[source]="source"
[displayMember]="'value'"
[valueMember]="'key'"
#sf="ngxMatSelect"
>
<mat-option [value]="option" *ngFor="let option of sf.filteredSource">
{{option.value}}
</mat-option>
</mat-select>
</mat-form-field>
component.ts:
import {Observable} from "rxjs";
import {of} from 'rxjs';
export class MyComponent implements OnInit {
bankValue = [{key: 10, value: 'Bank_10'},{key: 75, value: 'Bank_75'}];
source: any[] = [];
ngOnInit(): void {
for (let i = 0; i < 100; i++) {
this.source.push({value: 'Bank_' + i, key: i})
}
}
// server side mock search by 'of Observable'
bankSearcher = (search: string, pageNumber: number, pageSize: number): Observable<any[]> => {
return of(this.source.filter(w => w.value.includes(search)));
}
}
Property | Default Value | Options | Description |
---|---|---|---|
emptyLabel | No results found | string | label for no result found after search |
searchBoxPlaceholder | Search ... | string | `placeholder` for search box |
maximumResultForShow | 30 | number | For better performance (especially in mobile), you must set maximum record for showing the records |
valueMember | id | string | when your value is an object, it must be defined |
displayMember | name | string | for searching, it must be defined |
maxWidthForMobileView | 599.9 | number | unit is px |
useMobileView | true | boolean | if this value is true and your screen width is less than value of maxWidthForMobileView, 'mat-select' Will be displayed in 'FullScreen' or 'Bottom Sheet' |
mobileViewType | 'FullScreen' | 'BottomSheet' | string | |
lazyLoad | false | boolean | for use searcher function, it must be true |
source | [] | any[] | Initial source(it can be big data) |
filteredSource | [] | any[] | filtered data(you receive filtered records from 'NgxMatSelect' directive) |
searcher | (search: string, pageNumber: number, pageSize: number) => Observable<[]> | Function | for use lazy load you must define function that return ObserverOfArray |
hasSearchBox | true | boolean | |
title | null | string | |
inFirstLoadCallSearcher | false | boolean | |
inFirstLoadSearcherValue | '' | string | |
useInfiniteScroll | false | boolean |