File

feature-libs/asm/components/customer-selection/customer-selection.component.ts

Implements

OnInit OnDestroy

Metadata

host {
}
selector cx-customer-selection
templateUrl ./customer-selection.component.html

Index

Properties
Methods
Outputs

Constructor

constructor(fb: FormBuilder, asmService: AsmService, config: AsmConfig)
Parameters :
Name Type Optional
fb FormBuilder No
asmService AsmService No
config AsmConfig No

Outputs

submitEvent
Type : EventEmitter

Methods

closeResults
closeResults()
Returns : void
Protected handleSearchTerm
handleSearchTerm(searchTermValue: string)
Parameters :
Name Type Optional
searchTermValue string No
Returns : void
ngOnDestroy
ngOnDestroy()
Returns : void
ngOnInit
ngOnInit()
Returns : void
onDocumentClick
onDocumentClick(event: Event)
Parameters :
Name Type Optional
event Event No
Returns : void
onSubmit
onSubmit()
Returns : void
selectCustomerFromList
selectCustomerFromList(customer: User)
Parameters :
Name Type Optional
customer User No
Returns : void

Properties

customerSelectionForm
Type : FormGroup
resultList
Type : ElementRef
Decorators :
@ViewChild('resultList')
searchResults
Type : Observable<CustomerSearchPage>
searchResultsLoading$
Type : Observable<boolean>
searchTerm
Type : ElementRef
Decorators :
@ViewChild('searchTerm')
selectedCustomer
Type : User | undefined
submitEvent
Default value : new EventEmitter<{ customerId?: string }>()
Decorators :
@Output()
Protected subscription
Default value : new Subscription()
import {
  Component,
  ElementRef,
  EventEmitter,
  OnDestroy,
  OnInit,
  Output,
  ViewChild,
} from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { AsmConfig, AsmService, CustomerSearchPage } from '@spartacus/asm/core';
import { User } from '@spartacus/core';
import { Observable, Subscription } from 'rxjs';
import { debounceTime } from 'rxjs/operators';

@Component({
  selector: 'cx-customer-selection',
  templateUrl: './customer-selection.component.html',
  host: {
    '(document:click)': 'onDocumentClick($event)',
  },
})
export class CustomerSelectionComponent implements OnInit, OnDestroy {
  customerSelectionForm: FormGroup;
  protected subscription = new Subscription();
  searchResultsLoading$: Observable<boolean>;
  searchResults: Observable<CustomerSearchPage>;
  selectedCustomer: User | undefined;

  @Output()
  submitEvent = new EventEmitter<{ customerId?: string }>();

  @ViewChild('resultList') resultList: ElementRef;
  @ViewChild('searchTerm') searchTerm: ElementRef;

  constructor(
    protected fb: FormBuilder,
    protected asmService: AsmService,
    protected config: AsmConfig
  ) {}

  ngOnInit(): void {
    this.customerSelectionForm = this.fb.group({
      searchTerm: ['', Validators.required],
    });
    this.asmService.customerSearchReset();
    this.searchResultsLoading$ =
      this.asmService.getCustomerSearchResultsLoading();
    this.searchResults = this.asmService.getCustomerSearchResults();

    this.subscription.add(
      this.customerSelectionForm.controls.searchTerm.valueChanges
        .pipe(debounceTime(300))
        .subscribe((searchTermValue) => {
          this.handleSearchTerm(searchTermValue);
        })
    );
  }

  protected handleSearchTerm(searchTermValue: string) {
    if (
      !!this.selectedCustomer &&
      searchTermValue !== this.selectedCustomer.name
    ) {
      this.selectedCustomer = undefined;
    }
    if (Boolean(this.selectedCustomer)) {
      return;
    }
    this.asmService.customerSearchReset();
    if (searchTermValue.trim().length >= 3) {
      this.asmService.customerSearch({
        query: searchTermValue,
        pageSize: this.config.asm?.customerSearch?.maxResults,
      });
    }
  }

  selectCustomerFromList(customer: User) {
    this.selectedCustomer = customer;
    this.customerSelectionForm.controls.searchTerm.setValue(
      this.selectedCustomer.name
    );
    this.asmService.customerSearchReset();
  }

  onSubmit(): void {
    if (this.customerSelectionForm.valid && !!this.selectedCustomer) {
      this.submitEvent.emit({ customerId: this.selectedCustomer.customerId });
    } else {
      this.customerSelectionForm.markAllAsTouched();
    }
  }

  onDocumentClick(event: Event) {
    if (Boolean(this.resultList)) {
      if (
        this.resultList.nativeElement.contains(event.target) ||
        this.searchTerm.nativeElement.contains(event.target)
      ) {
        return;
      } else {
        this.asmService.customerSearchReset();
      }
    }
  }

  closeResults() {
    this.asmService.customerSearchReset();
  }

  ngOnDestroy(): void {
    this.subscription.unsubscribe();
    this.asmService.customerSearchReset();
  }
}
<form (ngSubmit)="onSubmit()" [formGroup]="customerSelectionForm">
  <label>
    <input
      aria-required="true"
      #searchTerm
      type="text"
      formControlName="searchTerm"
      placeholder="{{ 'asm.customerSearch.searchTerm.label' | cxTranslate }}"
    />
    <cx-form-errors
      aria-live="assertive"
      aria-atomic="true"
      [control]="customerSelectionForm.get('searchTerm')"
    ></cx-form-errors>
  </label>
  <button type="submit">
    {{ 'asm.customerSearch.submit' | cxTranslate }}
  </button>
</form>

<div *ngIf="searchResults | async as results" class="asm-results" #resultList>
  <button
    *ngFor="let result of results.entries"
    (click)="selectCustomerFromList(result)"
  >
    <span class="result-name">{{ result.name }}</span>
    <span class="result-id">{{ result.uid }}</span>
  </button>
  <button
    (click)="closeResults()"
    *ngIf="
      !(searchResultsLoading$ | async) &&
      searchTerm.value.length >= 3 &&
      !!results.entries &&
      results.entries.length <= 0
    "
  >
    {{ 'asm.customerSearch.noMatch' | cxTranslate }}
  </button>
</div>

<div class="asm-results" *ngIf="searchResultsLoading$ | async">
  <div
    class="spinner"
    aria-hidden="false"
    [attr.aria-label]="'common.loading' | cxTranslate"
  >
    <div></div>
    <div></div>
    <div></div>
  </div>
</div>
Legend
Html element
Component
Html element with directive

result-matching ""

    No results matching ""