Skip to content

Commit

Permalink
Merge pull request #15792 from sandrotonon/master
Browse files Browse the repository at this point in the history
fix(p-autocomplete) selectItem and multipleItems broken due to optionValue support
  • Loading branch information
cetincakiroglu authored Jun 13, 2024
2 parents 4f06c86 + 958ef29 commit ea1cdd9
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 5 deletions.
63 changes: 62 additions & 1 deletion src/app/components/autocomplete/autocomplete.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ import { AutoComplete } from './autocomplete';
})
class TestAutocompleteComponent {
brands: string[] = ['Audi', 'BMW', 'Fiat', 'Ford', 'Honda', 'Jaguar', 'Mercedes', 'Renault', 'Volvo', 'VW'];
cars: any[] = [{ brand: 'Volvo' }, { brand: 'VW' }];
cars: any[] = [
{ id: 1, brand: 'Volvo' },
{ id: 2, brand: 'VW' }
];
filteredBrands: any[];
filteredCars: any[];
brand: string;
Expand Down Expand Up @@ -473,6 +476,33 @@ describe('AutoComplete', () => {
flush();
}));

it('should set the optionValue property as value', fakeAsync(() => {
autocomplete2.optionValue = 'id';
fixture.detectChanges();

const inputEl = fixture.debugElement.queryAll(By.css('p-autoComplete'))[1].query(By.css('.p-inputtext.p-component'));
inputEl.nativeElement.dispatchEvent(new Event('focus'));
inputEl.nativeElement.focus();
inputEl.nativeElement.click();
fixture.detectChanges();

const onOptionSelectSpy = spyOn(autocomplete2, 'onOptionSelect').and.callThrough();
inputEl.nativeElement.value = 'v';
inputEl.nativeElement.dispatchEvent(new Event('keydown'));
inputEl.nativeElement.dispatchEvent(new Event('input'));
inputEl.nativeElement.dispatchEvent(new Event('keyup'));
tick(300);
fixture.detectChanges();

const firstItemEl = fixture.debugElement.queryAll(By.css('p-autoComplete'))[1].query(By.css('li')).nativeElement;
firstItemEl.click();
fixture.detectChanges();
expect(autocomplete2.value).toEqual(1);
expect(onOptionSelectSpy).toHaveBeenCalled();
expect(testComponent.car).toEqual(autocomplete2.value);
flush();
}));

it('should multiple', () => {
autocomplete.multiple = true;
fixture.detectChanges();
Expand Down Expand Up @@ -604,6 +634,37 @@ describe('AutoComplete', () => {
flush();
}));

it('should select property with multiSelect and optionValue', fakeAsync(() => {
autocomplete2.multiple = true;
autocomplete2.optionValue = 'id';
autocomplete2.optionLabel = 'brand';
autocomplete2.forceSelection = true;
fixture.detectChanges();

const inputEl = fixture.debugElement.queryAll(By.css('p-autoComplete'))[1].query(By.css('input'));
inputEl.nativeElement.dispatchEvent(new Event('focus'));
inputEl.nativeElement.click();
fixture.detectChanges();

const onOptionSelectSpy = spyOn(autocomplete2, 'onOptionSelect').and.callThrough();
inputEl.nativeElement.value = 'v';
inputEl.nativeElement.dispatchEvent(new Event('keydown'));
inputEl.nativeElement.dispatchEvent(new Event('input'));
inputEl.nativeElement.dispatchEvent(new Event('keyup'));
tick(300);
fixture.detectChanges();

inputEl.nativeElement.dispatchEvent(new Event('change'));
const firstItemEl = fixture.debugElement.queryAll(By.css('li'))[1].nativeElement;
firstItemEl.click();
fixture.detectChanges();
expect(autocomplete2.value[0]).toEqual(1);
expect(autocomplete2.value.length).toEqual(1);
expect(onOptionSelectSpy).toHaveBeenCalled();
expect(testComponent.car).toEqual(autocomplete2.value);
flush();
}));

it('should navigate with arrow keys and select with enter', () => {
fixture.detectChanges();

Expand Down
22 changes: 18 additions & 4 deletions src/app/components/autocomplete/autocomplete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ export const AUTOCOMPLETE_VALUE_ACCESSOR: any = {
[attr.aria-selected]="true"
>
<ng-container *ngTemplateOutlet="selectedItemTemplate; context: { $implicit: option }"></ng-container>
<span *ngIf="!selectedItemTemplate" class="p-autocomplete-token-label">{{ getOptionLabel(option) }}</span>
<span *ngIf="!selectedItemTemplate" class="p-autocomplete-token-label">{{ getMultipleLabel(option) }}</span>
<span class="p-autocomplete-token-icon" (click)="!readonly ? removeOption($event, i) : ''">
<TimesCircleIcon [styleClass]="'p-autocomplete-token-icon'" *ngIf="!removeIconTemplate" [attr.aria-hidden]="true" />
<span *ngIf="removeIconTemplate" class="p-autocomplete-token-icon" [attr.aria-hidden]="true">
Expand Down Expand Up @@ -778,10 +778,10 @@ export class AutoComplete implements AfterViewChecked, AfterContentInit, OnDestr

inputValue = computed(() => {
const modelValue = this.modelValue();
const selectedOption = this.optionValueSelected ? (this.suggestions || []).find((item: any) => ObjectUtils.resolveFieldData(item, this.optionValue) === modelValue) : modelValue;
const selectedOption = this.getSelectedOption(modelValue);

if (modelValue) {
if (typeof modelValue === 'object' || this.optionValueSelected) {
if (typeof modelValue === 'object' || this.optionValue) {
const label = this.getOptionLabel(selectedOption);

return label != null ? label : modelValue;
Expand Down Expand Up @@ -1592,7 +1592,7 @@ export class AutoComplete implements AfterViewChecked, AfterContentInit, OnDestr
}

getOptionValue(option) {
return this.optionValue ? ObjectUtils.resolveFieldData(option, this.optionValue) : option && option.value != undefined ? option.value : option;
return this.optionValue ? ObjectUtils.resolveFieldData(option, this.optionValue) : option;
}

getOptionIndex(index, scrollerOptions) {
Expand All @@ -1607,6 +1607,20 @@ export class AutoComplete implements AfterViewChecked, AfterContentInit, OnDestr
return this.optionGroupChildren ? ObjectUtils.resolveFieldData(optionGroup, this.optionGroupChildren) : optionGroup.items;
}

getSelectedOption(modelValue: any) {
if (!this.optionValue) {
return modelValue;
}

return (this.suggestions || []).find((item: any) => ObjectUtils.resolveFieldData(item, this.optionValue) === modelValue);
}

getMultipleLabel(option: any) {
let selected = this.getSelectedOption(option);

return this.getOptionLabel(selected);
}

registerOnChange(fn: Function): void {
this.onModelChange = fn;
}
Expand Down

0 comments on commit ea1cdd9

Please sign in to comment.