Custom Filter Function for Select Filter Feature


Topic: Custom Filter Function for Select Filter Feature

Kristian Mark Surat asked 3 years ago

Is there any documentation on how to customize the Filter Function for the Select Filter Feature?


Grzegorz Bujański staff commented 3 years ago

You mean this feature: https://mdbootstrap.com/docs/b5/angular/forms/select/#section-search? Unfortunately, it is not possible to pass a custom filtering function at the moment


malte pro premium commented 3 years ago

MDB4 had this feature that you can bind an formControl to the filter input. Any plans of implementing it in MDB5 to enable remote filtering?


Arkadiusz Idzikowski staff commented 3 years ago

@malte We currently don't plan to add such a feature to the select component. We deliberately moved the search process on the component side as it is difficult to manage the selection list when option components are destroyed/added in the ngFor loop.


Lumpenstein commented 2 years ago

Still not planned to re-implement this feature? Client asks to get the custom filter function back after I had to remove it migrating to mdb5 :/


malte pro premium answered 3 years ago

Ok well the data bind the select has tons of rows so client filtering is not an option.

Ive made an directive to "hack" into the filtering option. I kindly want to provide this snippet. Somehow the "Crate Snippet" Function seems to be broken so I hope its ok to post it here:

customfilter Directive

import { Directive, AfterContentInit, Input, EventEmitter, Output, OnChanges, SimpleChanges } from '@angular/core';
import { MdbSelectComponent } from 'mdb-angular-ui-kit/select';
import { skipWhile, debounceTime, tap } from 'rxjs/operators';
import { FormControl } from '@angular/forms';
@Directive({
    selector: '[customfilter]'
})
export class CustomfilterDirective implements AfterContentInit, OnChanges {


    @Input()
    public customfilter: MdbSelectComponent;

    @Input()
    public debounce = 300;

    @Input()
    public forwardToControl: FormControl;

    @Input()
    public isLoading = false;

    @Input()
    public loadingText = 'Loading...';

    @Input()
    public notFoundText = 'No results.';


    @Output()
    public filtered: EventEmitter<{
        searchControl: FormControl;
        val: unknown;
    }> = new EventEmitter<{
                searchControl: FormControl;
                val: unknown;
            }>();

    public ngAfterContentInit(): void {
        this._init();
    }

    public ngOnChanges(changes: SimpleChanges): void {
        if (changes.isLoading && this.customfilter) {
            if (this.isLoading) {
                this.customfilter.notFoundMsg =  this.loadingText;
            } else {
                this.customfilter.notFoundMsg = this.notFoundText;
            }
        }
    }

    private _init(): void {
        if (this.customfilter) {
            console.log ('Found MdbSelectComponent. Will now try to access the filter control...');

            if (this.customfilter.selectFilter) {
                console.log('Found select filter. Attaching...', this.customfilter.selectFilter);
                this.customfilter.notFoundMsg = 'Loading...';
                // We will update the not found message
                // to show we are actually loading results
                this.customfilter.selectFilter
                    .valueChanges
                    .pipe(skipWhile(x => !x || x === ''))
                    .pipe(tap(() => this.isLoading = true))
                    .pipe(debounceTime(this.debounce))
                    .subscribe(value => {
                        this.filtered.emit({
                            searchControl: this.customfilter?.selectFilter,
                            val: value
                        });

                        if(this.forwardToControl) {
                            this.forwardToControl.setValue(value, {
                                emitEvent: true
                            });
                        }
                    });
            }

        }
    }

}

Example

<mdb-select 
#mySelect
                [customfilter]="mySelect"
                [filter]="true"
              [forwardToControl]="form.controls.myCustomFormControl"></mdb-select>

This way it forwards the filter value to your custom formControl. You can also use the (filtered) output.

Once value of the original filter control changed it sets the loading state until you change it back (true/false). I "misuse" the noresults found text for propery displaying whats going on.


Please insert min. 20 characters.

FREE CONSULTATION

Hire our experts to build a dedicated project. We'll analyze your business requirements, for free.

Status

Answered

Specification of the issue
  • User: Free
  • Premium support: No
  • Technology: MDB Angular
  • MDB Version: MDB5 1.0.0-beta5
  • Device: PC
  • Browser: Chrome
  • OS: Linux
  • Provided sample code: No
  • Provided link: No