Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

mat-autocomplete filter to hightlight partial string matches

I am trying to achieve a filter with mat-autocomplete that is similar to the following example;

trade input example

So I am trying to achieve the functionality so that when a user begins to type in the trade they are looking for filters based on a partial string match anywhere in the string and highlight this in the option.

cheackatrade screenshot

I current have in my .html

<mat-form-field class="form-group special-input">
            <input type="text" placeholder="Select a trade" aria-label="Select a trade" matInput [formControl]="categoriesCtrl" [matAutocomplete]="auto">
            <mat-autocomplete #auto="matAutocomplete" md-menu-class="autocomplete">
                <mat-option *ngFor="let option of filteredOptions | async" [value]="option.name">
                    {{ option.name }} 
                </mat-option>
            </mat-autocomplete>
        </mat-form-field>

where my .ts is

categoriesCtrl: FormControl;

filteredOptions: Observable<ICategory[]>;
options: ICategory[];

categorySubscription: Subscription;

constructor(fb: FormBuilder, private router: Router, private service: SearchService, private http: Http) {

    this.categoriesCtrl = new FormControl();
}

ngOnInit() {

this.categorySubscription = this.service.getCategories().subscribe((categories: ICategory[]) => {

    this.options = categories;

    this.filteredOptions = this.categoriesCtrl.valueChanges
        .pipe(
        startWith(''),
        map(options => options ? this.filter(options) : this.options.slice())
        );
});    
}

ngOnDestroy() {
    this.categorySubscription.unsubscribe();
}

filter(val: string): ICategory[] {

    return this.options.filter(x =>
        x.name.toUpperCase().indexOf(val.toUpperCase()) !== -1);
}

ICategory is a basic interface.

export interface ICategory {
    value: number;
    name: string;  
}

And the service getCategories() just returns all the categories from an api.

The code is currently working and built per this example;

Angular Material mat-autocomplete example

I would like to add the effect of highlighting the term in the option string? Is this possible at all?

like image 765
Matthew Flynn Avatar asked Apr 04 '18 14:04

Matthew Flynn


People also ask

How do you use mat select autocomplete?

Simple autocompleteStart by creating the autocomplete panel and the options displayed inside it. Each option should be defined by a mat-option tag. Set each option's value property to whatever you'd like the value of the text input to be when that option is selected.

What is matAutocomplete?

The <mat-autocomplete>, an Angular Directive, is used as a special input control with an inbuilt dropdown to show all possible matches to a custom query. This control acts as a real-time suggestion box as soon as the user types in the input area.

Can't bind to matAutocomplete since it isn't a known property of input angular?

If 'mat-option' is an Angular component and it has 'value' input, then verify that it is part of this module. If 'mat-option' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule. schemas' of this component to suppress this message.


1 Answers

You can use a custom pipe to highlight the partial match whenever the user types in something in the filter.

@Pipe({ name: 'highlight' })
export class HighlightPipe implements PipeTransform {
  transform(text: string, search): string {
    const pattern = search
      .replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&")
      .split(' ')
      .filter(t => t.length > 0)
      .join('|');
    const regex = new RegExp(pattern, 'gi');

    return search ? text.replace(regex, match => `<b>${match}</b>`) : text;
  }
}

Demo

like image 163
bugs Avatar answered Sep 19 '22 21:09

bugs