How to make select filter work with http calls dynamically?


Topic: How to make select filter work with http calls dynamically?

dtrunk90 pro premium asked 6 months ago

I got it working to fill the select options dynamically but the search isn't working.And how to add a data-additional attribute to set from additionalData key?

My component class:

export class AppComponent implements OnInit {
  searchText = new Subject();
  filteredOptions: Observable<any[]>;
  options = [];

  constructor(private appService: AppService) { }

  ngOnInit() {
    this.appService.getJson()
      .subscribe((data: any) => {
        this.options = data.options.map((option : any) => {
          return {
            value: option.id,
            label: option.name,
            additionalData: option.additionalData.join(',')
          }
        });

        this.filteredOptions = this.searchText.pipe(
          startWith(''),
          map((value: string) => this.filter(value, this.options))
        );
      });
  }

  filter(value: string, options: any[]): any[] {
    const filterValue = value.toLowerCase();
    return options.filter((option: any) => {
      console.log(option, filterValue);
      return option.value.toLowerCase().includes(filterValue) || option.label.toLowerCase().includes(filterValue);
    });
  }
}

HTML:

<div class="md-form">
  <mdb-select-2 placeholder="Choose your option" label="Example label">
    <mdb-select-filter
      [ngModel]="searchText | async"
      (ngModelChange)="searchText.next($event)">
    </mdb-select-filter>
    <mdb-select-option *ngFor="let option of filteredOptions | async" [value]="option">{{ option.label }}</mdb-select-option>
  </mdb-select-2>
</div>

I don't get why the filter isn't working. It's nearly the same like in this autocomplete example: https://mdbootstrap.com/docs/angular/forms/autocomplete/#remoteData

I can see the console log output only once (on init) and not again when typing anything in the search/filter field.

EDIT: demo application: https://github.com/dtrunk90/mdb-select-filter-http You either need to add a SSH key to GitLab or change the SSH-based URL to the HTTPS based URL in package.json.


Grzegorz Bujański staff answered 6 months ago

I checked the project you shared. Just add FormsModule and ReactiveFormsModule to the imports in app.moudle.ts and it will work :)


dtrunk90 pro premium commented 6 months ago

Is that documented somewhere? I thought MDBBootstrapModulesPro.forRoot() will load/import all mdb bootstrap modules and nothing else is necessary?

EDIT: ok that's part of angular, not mdbootstrap. Thx. Will check if it works.


Grzegorz Bujański staff answered 6 months ago

Hi. You can add an additional attribute like this: [attr.data-additional] = "option.additionalData"> {{option.label}}

You don't need to add an extra parameter to the filter function.. Try the code below:

export class AppComponent implements OnInit {
  searchText = new Subject();
  filteredOptions: Observable<any[]>;
  options = [];

  constructor(private appService: AppService) { }

  ngOnInit() {
    this.appService.getJson()
      .subscribe((data: any) => {
        this.options = data.options.map((option : any) => {
          return {
            value: option.id,
            label: option.name,
            additionalData: option.additionalData.join(',')
          }
        });

        this.filteredOptions = this.searchText.pipe(
          startWith(''),
          map((value: string) => this.filter(value))
        );
      });
  }

  filter(value: string): any[] {
    const filterValue = value.toLowerCase();
    return this.options.filter((option: any) => {
      return option.value.toLowerCase().includes(filterValue) || option.label.toLowerCase().includes(filterValue);
    });
  }
}

HTML:

<div class="md-form">
  <mdb-select-2 placeholder="Choose your option" label="Example label">
    <mdb-select-filter
      [ngModel]="searchText | async"
      (ngModelChange)="searchText.next($event)">
    </mdb-select-filter>
    <mdb-select-option *ngFor="let option of filteredOptions | async" [value]="option" [attr.data-additional]="option.additionalData" >{{ option.label }}</mdb-select-option>
  </mdb-select-2>
</div>

dtrunk90 pro premium commented 6 months ago

Still not working. I'm using that extra parameter cause i want to use the method for another selectbox.


dtrunk90 pro premium commented 6 months ago

I've set up a demo application which loads the JSON from a file (see edited post). Filter isn't working there as well.


dtrunk90 pro premium commented 6 months ago

It looks like (ngModelChange) never gets called. I created a method onChange in AppComponent to console.log but there is no log output when typing something in the search box.


dtrunk90 pro premium answered 6 months ago

I've fixed it by using (inputChange) instead of (ngModelChange). It's not related to the HTTP call. Without it the filter wouldn't work too. It's due to (ngModelChange) will never get called. Maybe it's a bug?!


Please insert min. 20 characters.