diff --git a/projects/aca-content/src/lib/components/search/search-input-control/search-input-control.component.html b/projects/aca-content/src/lib/components/search/search-input-control/search-input-control.component.html index d701742896..609f50d887 100644 --- a/projects/aca-content/src/lib/components/search/search-input-control/search-input-control.component.html +++ b/projects/aca-content/src/lib/components/search/search-input-control/search-input-control.component.html @@ -5,7 +5,7 @@ mat-icon-button matPrefix class="app-search-button" - (click)="searchSubmit(searchTerm)" + (click)="searchSubmit()" [title]="'SEARCH.BUTTON.TOOLTIP' | translate" > search @@ -17,15 +17,14 @@ [attr.aria-label]="'SEARCH.INPUT.ARIA-LABEL' | translate" [type]="inputType" id="app-control-input" - [(ngModel)]="searchTerm" - (ngModelChange)="inputChange($event)" - (keyup.enter)="searchSubmit($event)" + [formControl]="searchFieldFormControl" + (keyup.enter)="searchSubmit()" [placeholder]="'SEARCH.INPUT.PLACEHOLDER' | translate" autocomplete="off" />
diff --git a/projects/aca-content/src/lib/components/search/search-input-control/search-input-control.component.spec.ts b/projects/aca-content/src/lib/components/search/search-input-control/search-input-control.component.spec.ts index 6af6c27bb3..e667a4e80a 100644 --- a/projects/aca-content/src/lib/components/search/search-input-control/search-input-control.component.spec.ts +++ b/projects/aca-content/src/lib/components/search/search-input-control/search-input-control.component.spec.ts @@ -43,31 +43,29 @@ describe('SearchInputControlComponent', () => { }); it('should emit submit event on searchSubmit', () => { - const keyboardEvent = { target: { value: 'a' } }; + component.searchTerm = 'mock-search-term'; - let eventArgs = null; - component.submit.subscribe((args) => (eventArgs = args)); + let submittedSearchTerm = ''; + component.submit.subscribe((searchTerm) => (submittedSearchTerm = searchTerm)); - component.searchSubmit(keyboardEvent); - expect(eventArgs).toBe(keyboardEvent); + component.searchSubmit(); + expect(submittedSearchTerm).toBe('mock-search-term'); }); it('should emit searchChange event on inputChange', () => { - const searchTerm = 'b'; + let emittedSearchTerm = ''; + component.searchChange.subscribe((searchTerm) => (emittedSearchTerm = searchTerm)); + component.searchTerm = 'mock-search-term'; - let eventArgs = null; - component.searchChange.subscribe((args) => (eventArgs = args)); - - component.inputChange(searchTerm); - expect(eventArgs).toBe(searchTerm); + expect(emittedSearchTerm).toBe('mock-search-term'); }); it('should emit searchChange event on clear', () => { - let eventArgs = null; - component.searchChange.subscribe((args) => (eventArgs = args)); + let emittedSearchTerm: string = null; + component.searchChange.subscribe((searchTerm) => (emittedSearchTerm = searchTerm)); component.clear(); - expect(eventArgs).toBe(''); + expect(emittedSearchTerm).toBe(''); }); it('should clear searchTerm', () => { diff --git a/projects/aca-content/src/lib/components/search/search-input-control/search-input-control.component.ts b/projects/aca-content/src/lib/components/search/search-input-control/search-input-control.component.ts index 23259a0f2d..3186fa9809 100644 --- a/projects/aca-content/src/lib/components/search/search-input-control/search-input-control.component.ts +++ b/projects/aca-content/src/lib/components/search/search-input-control/search-input-control.component.ts @@ -22,25 +22,28 @@ * from Hyland Software. If not, see . */ -import { Component, ElementRef, EventEmitter, Input, Output, ViewChild, ViewEncapsulation } from '@angular/core'; +import { Component, EventEmitter, Input, Output, ViewEncapsulation, ViewChild, ElementRef, OnInit, inject, DestroyRef } from '@angular/core'; import { CommonModule } from '@angular/common'; import { TranslateModule } from '@ngx-translate/core'; import { MatButtonModule } from '@angular/material/button'; import { MatIconModule } from '@angular/material/icon'; import { MatFormFieldModule } from '@angular/material/form-field'; import { MatInputModule } from '@angular/material/input'; -import { FormsModule } from '@angular/forms'; +import { FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; @Component({ standalone: true, - imports: [CommonModule, TranslateModule, MatButtonModule, MatIconModule, MatFormFieldModule, MatInputModule, FormsModule], + imports: [CommonModule, TranslateModule, MatButtonModule, MatIconModule, MatFormFieldModule, MatInputModule, FormsModule, ReactiveFormsModule], selector: 'app-search-input-control', templateUrl: './search-input-control.component.html', styleUrls: ['./search-input-control.component.scss'], encapsulation: ViewEncapsulation.None, host: { class: 'app-search-control' } }) -export class SearchInputControlComponent { +export class SearchInputControlComponent implements OnInit { + private readonly destroyRef = inject(DestroyRef); + /** Type of the input field to render, e.g. "search" or "text" (default). */ @Input() inputType = 'text'; @@ -63,14 +66,27 @@ export class SearchInputControlComponent { @ViewChild('searchInput', { static: true }) searchInput: ElementRef; - searchTerm = ''; + searchFieldFormControl = new FormControl(''); + + get searchTerm(): string { + return this.searchFieldFormControl.value.replace('text:', 'TEXT:'); + } + + set searchTerm(value: string) { + this.searchFieldFormControl.setValue(value); + } - searchSubmit(event: any) { - this.submit.emit(event); + ngOnInit() { + this.searchFieldFormControl.valueChanges.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((searchTermValue) => { + this.searchFieldFormControl.markAsTouched(); + this.searchChange.emit(searchTermValue); + }); } - inputChange(event: any) { - this.searchChange.emit(event); + searchSubmit() { + if (!this.searchFieldFormControl.errors) { + this.submit.emit(this.searchTerm); + } } clear() {