This is An Angular library that contains a facet search bar component, based on Angular team's Material Design components. Google uses something similar in some of their internal portals like Cloud Console and G-Suite Admin Console.
Try Example App - (Edit on StackBlitz ⚡️)
Try Table Example on Github API - (Edit on StackBlitz ⚡️)
npm i ng-material2-facet-search
- Import
NgMaterial2FacetSearchModule
module inapp.module.ts
- Add
ng-material2-facet-search
directive in your component, and configure it as you like.
app.component.html
<ng-material2-facet-search
[source]="facets"
(searchUpdated)="filterUpdated($event)"
dateFormat="M/d/yyyy"
[chipLabelsEnabled]="true" [confirmOnRemove]="true"
[clearButtonEnabled]="true" placeholder="Add a filter..." clearButtonText="CLEAR FILTERS">
</ng-material2-facet-search>
app.component.ts
import { Component, OnInit } from '@angular/core';
import { Facet, FacetDataType } from 'ng-material2-facet-search';
import { of } from 'rxjs';
import { delay, map } from 'rxjs/operators';
import { MyRemoteService } from './MyComponent/remove.service.ts'
@Component({
selector: 'app-component',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
// Facet Definitions
// You can either define and configure your facets as static object array,
// or you can generate dynamically based on your data from back end.
public facets: Array<Facet> = [{
// facet's object name
name: 'userName',
// label text for ui (optional)
text: 'User Name',
// type of the facet, options are;
// "Text" (input), "Boolean" (checkbox),
// "Category" (multi select), "CategorySingle" (single select),
// "Typeahead" (multi select typeahead), "TypeaheadSingle" (single select typeahead)
// "Date" (date picker) and "DateRange" (date pickers)
type: FacetDataType.Text,
// description text for ui (optional)
description: 'Please enter your user name (simple text input example)',
// name of the material icon (optional) (https://material.io/tools/icons)
icon: 'person_outline',
// you can set a facet as readonly to disable editing.
readonly: false,
// Typeahead related fields:
// Typehaead function
typeahead: function(txt){
// Call to external service that maps to FacteOptions
// See "Cities" Facet below
},
// Typehead debouce (in milliseconds) (default: 300)
typeahedDebounce: 300
}, {
name: 'birthday',
text: 'Birthday',
icon: 'date_range',
description: 'Please select your birthday (date select example)',
type: FacetDataType.Date,
}, {
name: 'eventDays',
text: 'Event Days',
icon: 'event_available',
description: 'Please select start and end dates (date range select example)',
type: FacetDataType.DateRange,
}, {
name: 'isParticipant',
text: 'Is a Participant?',
icon: 'live_help',
description: 'This is a test field, you can test boolean data type.',
type: FacetDataType.Boolean,
}, {
name: 'state',
text: 'State',
description: 'Please select something (single select, http example)',
type: FacetDataType.CategorySingle,
icon: 'folder_open',
/* mock http service call */
// you can define this facet's selection items as observable array, or fixed array.
options: of([
{ value: 'open', text: 'Open', count: 49 },
{ value: 'closed', text: 'Closed', count: 23 }
]).pipe(delay(700))
}, {
name: 'license',
text: 'License(s)',
description: 'Please select your licenses (multi select, http example)',
type: FacetDataType.Category,
icon: 'drive_eta',
/* mock http service call */
options: of([
{ value: 'a', text: 'Class A' },
{ value: 'b', text: 'Class B' },
{ value: 'c', text: 'Class C' }
]).pipe(delay(1200))
}, {
name: 'city',
text: 'Cities',
description: 'Please select from cities.',
type: FacetDataType.Typeahead,
icon: 'location_city',
/* mock http service call */
typeahead: function(txt){
const params = {
search: txt,
size: 5 // Limit results to show in Typeahead
}
return this.MyRemoteService.query(params)
.pipe(map((response) => {
// Map results to FacetsOptions for selection
response.results.map(item => ({
text: item.name,
value: item.value
}))
})
}
}
];
constructor() {
}
ngOnInit(): void {
}
// you can use an event method like this to trigger your filtering logic.
filterUpdated = (facetFilters: Array<Facet>): void => {
console.log('filter', facetFilters);
}
}
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.