Best way to use mdb-auto-completer


Topic: Best way to use mdb-auto-completer

univlearning pro asked 5 years ago

Hi,

I want to know what is the best way to use mdb-audo-completer for the next scenario:

I have remote data (from one http request) and I want to autocomplete my input according to the user entry. Once the user select one option (e.g. with enter key or click), I want to enable another input with other remote data (from one http request according to the first input selection) and I want to autocomplete this input too.

Thanks.


Bartosz Termena staff answered 5 years ago

Dear @univlearning

You should check out our autocomplete documentation: https://mdbootstrap.com/docs/angular/forms/autocomplete/

Go to the EXAMPLES & CUSTOMIZATION tab,

and then scroll down to the Second dependent on the first

Best Regards, Bartosz.


univlearning pro answered 5 years ago

Hi,

Thanks for your reply. I would like to know other things about it:

  1. Is it possible for both data to be filled with remote information (such as through an http request)?
  2. Is it possible to disable the second input until the first one is selected?
  3. How do I access the selected data in both text fields? That is, how do I capture the data once it is selected to invoke other methods?

Thanks again.


Bartosz Termena staff answered 5 years ago

Dear @univlearning

1) Yes, it is possible - Check our documentation https://mdbootstrap.com/docs/angular/forms/autocomplete/, then go to the EXAMPLES & CUSTOMIZATION tab, and scroll down to the Remote call after input event

2) Yes, it is possible - you could for example use *ngIf directive to check if this element has a value. Here is my code updated from Second dependent on the first:

app.component.html

 <div class="row">
  <div class="col-md-4 mx-auto-my-5">
    <div class="md-form">
      <input
        #firstInput
        type="text"
        [ngModel]="searchText | async"
        (ngModelChange)="searchText.next($event)"
        class="completer-input form-control mdb-autocomplete mb-0"
        [mdbAutoCompleter]="auto"
        placeholder="Choose your color"
      />
      <mdb-auto-completer #auto="mdbAutoCompleter" textNoResults="I have found no results :(">
        <mdb-option *ngFor="let option of results | async" [value]="option">
          <div class="d-flex flex-column">
            {{ option }}
          </div>
        </mdb-option>
      </mdb-auto-completer>
    </div>
  </div>

  <div class="col-md-4 mx-auto-my-5" *ngIf="firstInput.value.length !== 0">
    <div class="md-form">
      <input
        type="text"
        [ngModel]="searchText2 | async"
        (ngModelChange)="searchText2.next($event)"
        class="completer-input form-control mdb-autocomplete mb-0"
        [mdbAutoCompleter]="auto2"
        placeholder="Choose your color"
      />
      <mdb-auto-completer #auto2="mdbAutoCompleter" textNoResults="I have found no results :(">
        <mdb-option *ngFor="let option of results2 | async" [value]="option">
          <div class="d-flex flex-column">
            {{ option }}
          </div>
        </mdb-option>
      </mdb-auto-completer>
    </div>
  </div>
</div>

3) Again I refer you to the documentation - in Second dependent on the first .

searchText in updateSecondCompleterData() method is your data from the first input, try to do the same to the second input.

Best Regards, Bartosz.


univlearning pro answered 5 years ago

Hi,

Thanks again for your reply. I'm working with your suggestions, and I'm getting this console log when I push "arrow up" key:

Log result after "arrow up" key

I would like to know the reason of that.

Another thing that I want to implement is: Can I update the data for the second input once it is modified? (e.g. I write two letters for the second input and I want to search new results with this criteria by my http service)

Thanks again.


Bartosz Termena staff answered 5 years ago

Dear @univlearning

1) Could you share your code with me? In my case i don't get any error (work with code from documentation)

2) that's exactly how autocompleter from: https://mdbootstrap.com/docs/angular/forms/autocomplete/ -

EXAMPLES & CUSTOMIZATION/Remote call after input event works.

You can use this example for your second input.

Best Regards, Bartosz.


univlearning pro answered 5 years ago

Hi again,

1) For instance, this fails when there are no results and I push "Arrow up" key:

HTML

<div>
  <div class="row" *ngIf="firstData && firstData.length > 0">
    <div class="col-md-6 mx-auto-my-5">
      <div class="md-form">
        <input #firstField type="text" [ngModel]="firstDataCriteria | async" (ngModelChange)="firstDataCriteria.next($event)" class="completer-input form-control mdb-autocomplete mb-0" [mdbAutoCompleter]="firstFieldAutocompleter" placeholder="Select first">
        <mdb-auto-completer #firstFieldAutocompleter="mdbAutoCompleter" textNoResults="No results 1">
          <mdb-option *ngFor="let item of firstDataFiltered | async" [value]="item.name">
            {{ item.name }}
          </mdb-option>
        </mdb-auto-completer>
      </div>
    </div>
    <div class="col-md-6 mx-auto-my-5">
      <div class="md-form" *ngIf="firstField.value.length > 0">
        <input #secondField type="text" [ngModel]="secondDataCriteria | async" (ngModelChange)="secondDataCriteria.next($event)" class="completer-input form-control mdb-autocomplete mb-0" [mdbAutoCompleter]="secondFieldAutocompleter" placeholder="Select second">
        <mdb-auto-completer #secondFieldAutocompleter="mdbAutoCompleter" textNoResults="No results">
          <mdb-option *ngFor="let item of secondDataFiltered | async" [value]="item.name">
            {{ item.name }}
          </mdb-option>
        </mdb-auto-completer>
      </div>
    </div>
  </div>
</div>

TS

firstData: any[];
firstDataCriteria: Subject<string>;
firstDataFiltered: Observable<any>;
secondData: any[];
secondDataCriteria: Subject<string>;
secondDataFiltered: Observable<any>;

constructor(private httpClient: HttpClient) {
    this.firstDataCriteria = new Subject();
    this.secondDataCriteria = new Subject();
}

ngOnInit() {
    this.getFirstData();
    this.firstDataFiltered = this.firstDataCriteria.pipe(
        startWith(''),
        map((value: string) => this.filterFirstData(value))
    );
    this.secondDataFiltered = this.secondDataCriteria.pipe(
        startWith(''),
        tap(value => this.getSecondData()),
        map(value => this.filterSecondData(value))
    );
}

getFirstData() {
    this.httpClient
        .get('https://restcountries.eu/rest/v2/all')
        .subscribe((response: any[]) => (this.firstData = response));
}

filterFirstData(value) {
    return this.firstData.filter(item =>
        item.name.toLowerCase().includes(value.toLowerCase())
    );
}

getSecondData() {
    this.httpClient
        .get('https://restcountries.eu/rest/v2/all')
        .subscribe((response: any[]) => (this.secondData = response));
}

filterSecondData(value) {
    return this.secondData.filter(item =>
        item.name.toLowerCase().includes(value.toLowerCase())
    );
}

2) Ok, got it. Thanks.

I was also looking for a way to make these text fields look like a combo box, so that the user understood that when clicking, autocomplete options are loaded, but I couldn't find it. This is possible?

Thanks again.


Bartosz Termena staff answered 5 years ago

Hi @univlearning!

1) This problem will be fixed in next version

2) Try to change rxjs Subject to BehaviorSubject.

A BehaviorSubject holds one value. When it is subscribed it emits the value immediately. A Subject doesn't hold a value. In short - using BehaviorSubject after click the input the user will immediately see the item.results

Here is my code, based on https://mdbootstrap.com/docs/angular/forms/autocomplete/ EXAMPLES & CUSTOMIZATION/Remote call after input event:

  searchText = new BehaviorSubject<string>('');
  results: Observable<any>;
  url = 'https://swapi.co/api/people/?search=';

  constructor(private http: HttpClient) {}

  ngOnInit() {
    this.results = this.searchText.pipe(
      startWith(this.searchText),
      switchMap((searchText: string) => this.getRemoteData(searchText))
    );
  }

  getRemoteData(searchText: string) {
    return this.http.get(this.url + searchText).pipe(
      debounceTime(250),
      map((items: any) => items.results)
    );
  }

Now you can go ahead and try checking in getRemoteData() for ex. if the items.results.length is equal to 0, then show different textNoResults.

Best Regards, Bartosz.


univlearning pro answered 5 years ago

Hi,

1) Ok, I'll be ready for the update. Thanks.

2) Actually, I was wondering about the visual aspect, I mean, is it posible to give this aspect:

Select with material design

to the input?, I was thinking about the user experience, and maybe it is more understable with an icon or something that helps to navigate like: "If I click here, it displays a set of options, and I can search for my option once I've clicked over the field".

Best regards, and thanks again.


Bartosz Termena staff commented 5 years ago

2) Great idea! We'll think about implementing it in the future, maybe in the next version.

Best Regards, Bartosz.


univlearning pro commented 5 years ago

Great! Thank you for considering this implementation. I will look forward to the release of the new versions.


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: Pro
  • Premium support: No
  • Technology: MDB Angular
  • MDB Version: 8.0.0
  • Device: All
  • Browser: All
  • OS: All
  • Provided sample code: No
  • Provided link: No