#angular #typehead
Вопрос:
Я хочу создать форму, в которой вводимые заголовки будут добавляться динамически. Заголовок типа содержит типы контактов. Для каждой записи я хочу вывести свой собственный тип контакта. Количество полей ввода может быть определено пользователем. Как все это может быть реализовано с помощью компонента typeahead? Если у меня в форме несколько заголовков, при нажатии на них открывается окно поиска всех заголовков. В настоящее время это выглядит так:
<div formArrayName="contacts">
<div *ngFor="let contact of customerForm.get('contacts')['controls']; let i = index">
<div formGroupName="{{ i }}">
<div class="mb-2">
<div class="row">
<div>
<input type="hidden" id="contactId" formControlName="id">
</div>
<div class="col-6">
<label for="name">{{ 'customereditcomponent.label_ContactValue' | translate }}</label>
<input type="text" class="form-control" id="contactValue" formControlName="value">
</div>
<div class="col-5">
<div>
<ng-template #contactTypeTemplate let-contactType="result">
<div *ngIf="contactType.description != null">{{contactType.description}}</div>
</ng-template>
<label for="contactType{{i}}">{{ 'customereditcomponent.label_ContactType' | translate }}</label>
<div class="input-group">
<input id="contactType{{i}}" type="text" class="form-control" [ngbTypeahead]="searchContactTyppe" (focus)="focusContactType$.next($any($event).target.value)" (click)="clickContactType$.next($any($event).target.value)" [inputFormatter]="ContactTypeFormatter" [resultTemplate]="contactTypeTemplate" (selectItem)="selectedContactType($event)" #instanceContactType="ngbTypeahead" />
<div class="input-group-append">
<span class="input-group-text"><i class="feather icon-search"></i></span>
</div>
</div>
</div>
</div>
<div *ngIf="selectedCustomer == null " class="col-1">
<button type="button" class="btn btn-link" (click)="deleteContact(i)"><i class="fas fa-times"></i></button>
</div>
</div>
</div>
</div>
</div>
</div>
Контакты могут быть добавлены пользователем динамически.
import '...'
@Component({
selector: 'app-customer-edit',
templateUrl: './customer-edit.component.html',
styleUrls: ['./customer-edit.component.scss']
})
export class CustomerEditComponent implements OnInit {
customerForm: FormGroup;
contactTypes;
contactType: ContactType;
@ViewChild('instanceContactType') instanceContactType: NgbTypeahead;
focusContactType$ = new Subject<string>();
clickContactType$ = new Subject<string>();
constructor() { }
ngOnInit(): void {
this.customerForm = new FormGroup( {
id: new FormControl(),
externalId: new FormControl(),
isCompany: new FormControl(),
mainAddress: new FormGroup({
firstName: new FormControl(),
name: new FormControl(),
companyName: new FormControl(),
street: new FormControl(),
zipcode: new FormControl(),
city: new FormControl()
}),
customerAddresses: new FormArray([]),
contacts: new FormArray([]),
contactPersons: new FormArray([])
});
this.loadContactTypes();
}
selectNewContactType(contactType: ContactType): void {
this.loadContactTypes();
this.contactType = contactType;
this.instanceContactType.writeValue(contactType);
}
loadContactTypes(): void {
this.contactTypes = [];
this.contactTypes = this.contactTypes.concat(
new ContactType('-1', 'Neuer Kontakttyp'));
this.contactTypes = this.contactTypes.concat(this.basicDataService.getContactTypes());
}
selectedContactType(item): void{
const contactType: ContactType = item.item;
if (contactType.id === '-1' ) {
this.openModalDialog(this.createNewContactType);
} else {
this.contactType = item.item;
}
}
searchContactTyppe: OperatorFunction<string, readonly string[]> = (text$: Observable<string>) => {
const debouncedText$ = text$.pipe(debounceTime(200), distinctUntilChanged());
const clicksWithClosedPopup$ = this.clickContactType$.pipe(filter(() => !this.instanceContactType.isPopupOpen()));
const inputFocus$ = this.focusContactType$;
return merge(debouncedText$, inputFocus$, clicksWithClosedPopup$).pipe(
map(term => (term === '' ? this.contactTypes
: this.contactTypes.filter(v => v.description?.toLowerCase().indexOf(term.toLowerCase()) > -1)).slice(0, 10))
);
}
ContactTypeFormatter = (x: ContactType) => x.description;
}
Is it possible to use the Typehead in for something like this? If not, are there any alternatives?