Holiday Notice: Support will be provided on a limited scale from December 24th, 2024, to January 2nd, 2025. Happy holidays and a wonderful New Year!


Topic: Autocomplete Selected Item

CWI_MDB priority asked 2 years ago


Hi,

Can anyone provide an example of how to get the selected item from an autocomplete? I also need to preset the value when the page loads, based on certain conditions, can anyone explain how this is done? I've tried this.siteForm.get('customer')?.patchValue('Test Customer'); but that doesn't work. (Using Reactive Forms)

Resources (screenshots, code snippets etc.)

HTML

<div class="p-2" [ngClass]="{ 'pb-4': customer?.invalid && (customer?.dirty || customer?.touched) }">
      <mdb-form-control>
        <input mdbInput mdbValidate [ngModel]="searchText | async" (ngModelChange)="searchText.next($event)" [mdbAutocomplete]="autocomplete" type="text" id="customer" formControlName="customer" class="form-control" required />
        <label mdbLabel class="form-label" for="customer">Customer search *</label>
        <mdb-error *ngIf="customer?.invalid && (customer?.dirty || customer?.touched)">Customer is required</mdb-error>
        <div *ngIf="loading" class="autocomplete-loader spinner-border" role="status"></div>
      </mdb-form-control>
      <mdb-autocomplete #autocomplete="mdbAutocomplete" [displayValue]="displayValue" (opened)="onOpen()" (selected)="customerSelected()">
        <mdb-option *ngFor="let option of results | async" [value]="option">
          {{ option.name }}
        </mdb-option>
        <div *ngIf="notFound" class="autocomplete-no-results">No results found</div>
      </mdb-autocomplete>
    </div>

TS

export class SiteDetailsComponent implements OnInit {

  public id: any;
  public site: any = { identifier: null, name: '', customer: null, address: {} };
  public searchText = new Subject<string>();
  public results: Observable<any>;
  public notFound: boolean = false;
  public loading: boolean = false;
  public dataLoaded: boolean = false;
  public selectedCustomer = null;
  public saving: boolean = false;
  public errorMessage = null;
  notificationRef: MdbNotificationRef<ToastComponent> | null = null;

  public siteForm = new FormGroup({
    customer: new FormControl(this.site.customer, { validators: Validators.required, updateOn: 'change' }),
  });

  public types: any;

  get customer() { return this.siteForm.get('customer'); }

  constructor(private route: ActivatedRoute, private notificationService: MdbNotificationService, private customerService: CustomerService, private siteService: SiteService) {
    this.results = this.searchText.pipe(
      debounceTime(250),
      switchMap((value: string) => this.filter(value)),
      tap((results: any) =>
        results.length > 0 ? (this.notFound = false) : (this.notFound = true)
      )
    );

    this.customer?.valueChanges
      .pipe(filter(
        newValue => typeof newValue != 'string')
      )
      .subscribe(newValue => {
        this.selectedCustomer = newValue;
      });
  }

  ngOnInit(): void {

  }

  filter(value: string): any {
    if (!value) return of();

    const filterValue = value.toLowerCase();
    this.loading = true;

    return this.customerService.searchByName(encodeURI(filterValue)).pipe(
      map((data: any) => {
        return data;
      }),
      delay(300),
      tap(() => (
        this.loading = false
      ))
    );
  }

  displayValue(value: any): string {
    return value ? value.name : '';
  }

  onOpen(): void {
    if (!this.dataLoaded) {
      this.searchText.next('');
      this.dataLoaded = true;
    }
  }

  customerSelected(): void {
    console.log('option selected');
  }

}

Thanks!


Arkadiusz Idzikowski staff answered 2 years ago


Here is an example showing how to set value using patchValue method and how to get selected value from the emitted event:

HTML:

<form [formGroup]="formGroup">
  <mdb-form-control>
    <input
      mdbInput
      formControlName="autocomplete"
      [mdbAutocomplete]="autocomplete"
      type="text"
      id="autocomplete"
      class="form-control"
    />
    <label mdbLabel class="form-label" for="autocomplete">Example label</label>
  </mdb-form-control>
  <mdb-autocomplete #autocomplete="mdbAutocomplete" (selected)="onSelect($event)">
    <mdb-option *ngFor="let option of results | async" [value]="option">
      {{ option }}
    </mdb-option>
    <div *ngIf="notFound" class="autocomplete-no-results">No results found</div>
  </mdb-autocomplete>
</form>

TS:

  reactiveControl = new FormControl();
  results: Observable<string[]>;
  notFound = false;
  data = ['One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight'];

  formGroup = new FormGroup({
    autocomplete: new FormControl(null),
  });

  constructor() {
    this.results = this.autocomplete.valueChanges.pipe(
      startWith(''),
      map((value: string) => this.filter(value)),
      tap((results: string[]) =>
        results.length > 0 ? (this.notFound = false) : (this.notFound = true)
      )
    );
  }

  ngOnInit() {
    this.autocomplete.patchValue('Two');
  }

  filter(value: string): string[] {
    const filterValue = value.toLowerCase();
    return this.data.filter((item: string) =>
      item.toLowerCase().includes(filterValue)
    );
  }

  onSelect(event: MdbAutocompleteSelectedEvent) {
    console.log('Selected value:', event.option.value);
  }

  get autocomplete(): AbstractControl {
    return this.formGroup.get('autocomplete')!;
  }

CWI_MDB priority commented 2 years ago

Great, thanks for your help!

Is this event listed in the documentation? I can't seem to find it so I'm just wondering, for future issues, if there is anywhere else I should be looking?



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

  • ForumUser: Priority
  • Premium support: Yes
  • Technology: MDB Angular
  • MDB Version: MDB5 2.3.0
  • Device: PC
  • Browser: Chrome
  • OS: Windows 10
  • Provided sample code: No
  • Provided link: No