File
Implements
Metadata
| host |
{ } |
| selector |
cx-customer-selection |
| templateUrl |
./customer-selection.component.html |
Index
Properties
|
|
|
Methods
|
|
|
Outputs
|
|
|
Methods
|
closeResults
|
closeResults()
|
|
|
|
|
|
Protected
handleSearchTerm
|
handleSearchTerm(searchTermValue: string)
|
|
|
Parameters :
| Name |
Type |
Optional |
| searchTermValue |
string
|
No
|
|
|
ngOnDestroy
|
ngOnDestroy()
|
|
|
|
|
|
onDocumentClick
|
onDocumentClick(event: Event)
|
|
|
Parameters :
| Name |
Type |
Optional |
| event |
Event
|
No
|
|
|
selectCustomerFromList
|
selectCustomerFromList(customer: User)
|
|
|
Parameters :
| Name |
Type |
Optional |
| customer |
User
|
No
|
|
|
resultList
|
Type : ElementRef
|
Decorators :
@ViewChild('resultList')
|
|
|
|
searchResultsLoading$
|
Type : Observable<boolean>
|
|
|
|
searchTerm
|
Type : ElementRef
|
Decorators :
@ViewChild('searchTerm')
|
|
|
|
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 with directive