How to make select filter work with http calls dynamically?


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

dtrunk90 free asked 1 year 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 1 year ago

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


dtrunk90 free commented 1 year 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.


dtrunk90 free answered 1 year 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?!


Grzegorz Bujański staff answered 1 year 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 free commented 1 year ago

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


dtrunk90 free commented 1 year 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 free commented 1 year 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.


Please insert min. 20 characters.

FREE CONSULTATION

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

Status

Resolved

Specification of the issue
  • User: Free
  • Premium support: No
  • Technology: MDB Angular
  • MDB Version: 9.4.0
  • Device: Desktop
  • Browser: Firefox
  • OS: Linux Ubuntu
  • Provided sample code: No
  • Provided link: Yes