mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-31 17:38:48 +00:00
[ADF-2002] added ARROW support for search autocomplete results (#2732)
* [ADF-2002] added arrow up and down feature * [ADF-2002] fixed search bar animation and added arrow support * [ADF-2002] added some test for arrow manage
This commit is contained in:
@@ -10,13 +10,15 @@
|
|||||||
</a>
|
</a>
|
||||||
<mat-form-field class="adf-input-form-field-divider">
|
<mat-form-field class="adf-input-form-field-divider">
|
||||||
<input matInput
|
<input matInput
|
||||||
|
#inputSearch
|
||||||
[type]="inputType"
|
[type]="inputType"
|
||||||
[autocomplete]="getAutoComplete()"
|
[autocomplete]="getAutoComplete()"
|
||||||
id="adf-control-input"
|
id="adf-control-input"
|
||||||
[(ngModel)]="searchTerm"
|
[(ngModel)]="searchTerm"
|
||||||
(focus)="activateToolbar()"
|
(focus)="activateToolbar($event)"
|
||||||
(blur)="onBlur($event)"
|
(blur)="onBlur($event)"
|
||||||
(keyup.escape)="toggleSearchBar()"
|
(keyup.escape)="toggleSearchBar()"
|
||||||
|
(keyup.arrowdown)="selectFirstResult()"
|
||||||
(ngModelChange)="inputChange($event)"
|
(ngModelChange)="inputChange($event)"
|
||||||
[searchAutocomplete]="auto"
|
[searchAutocomplete]="auto"
|
||||||
(keyup.enter)="searchSubmit($event)">
|
(keyup.enter)="searchSubmit($event)">
|
||||||
@@ -36,6 +38,8 @@
|
|||||||
[tabindex]="0"
|
[tabindex]="0"
|
||||||
(focus)="onFocus($event)"
|
(focus)="onFocus($event)"
|
||||||
(blur)="onBlur($event)"
|
(blur)="onBlur($event)"
|
||||||
|
(keyup.arrowdown)="onRowArrowDown($event)"
|
||||||
|
(keyup.arrowup)="onRowArrowUp($event)"
|
||||||
class="adf-search-autocomplete-item"
|
class="adf-search-autocomplete-item"
|
||||||
(click)="elementClicked(item)"
|
(click)="elementClicked(item)"
|
||||||
(keyup.enter)="elementClicked(item)">
|
(keyup.enter)="elementClicked(item)">
|
||||||
|
@@ -55,6 +55,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&-search-autocomplete-item {
|
&-search-autocomplete-item {
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: mat-color($background, 'hover');
|
background-color: mat-color($background, 'hover');
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
|
@@ -69,6 +69,13 @@ describe('SearchControlComponent', () => {
|
|||||||
TestBed.resetTestingModule();
|
TestBed.resetTestingModule();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
function typeWordIntoSearchInput(word: string): void {
|
||||||
|
let inputDebugElement = debugElement.query(By.css('#adf-control-input'));
|
||||||
|
inputDebugElement.nativeElement.value = word;
|
||||||
|
inputDebugElement.nativeElement.focus();
|
||||||
|
inputDebugElement.nativeElement.dispatchEvent(new Event('input'));
|
||||||
|
}
|
||||||
|
|
||||||
describe('when input values are inserted', () => {
|
describe('when input values are inserted', () => {
|
||||||
|
|
||||||
beforeEach(async(() => {
|
beforeEach(async(() => {
|
||||||
@@ -83,18 +90,12 @@ describe('SearchControlComponent', () => {
|
|||||||
expect(value).toBe('customSearchTerm');
|
expect(value).toBe('customSearchTerm');
|
||||||
});
|
});
|
||||||
|
|
||||||
let inputDebugElement = debugElement.query(By.css('#adf-control-input'));
|
typeWordIntoSearchInput('customSearchTerm');
|
||||||
inputDebugElement.nativeElement.value = 'customSearchTerm';
|
|
||||||
inputDebugElement.nativeElement.focus();
|
|
||||||
inputDebugElement.nativeElement.dispatchEvent(new Event('input'));
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should update FAYT search when user inputs a valid term', async(() => {
|
it('should update FAYT search when user inputs a valid term', async(() => {
|
||||||
let inputDebugElement = debugElement.query(By.css('#adf-control-input'));
|
typeWordIntoSearchInput('customSearchTerm');
|
||||||
inputDebugElement.nativeElement.value = 'customSearchTerm';
|
|
||||||
inputDebugElement.nativeElement.focus();
|
|
||||||
inputDebugElement.nativeElement.dispatchEvent(new Event('input'));
|
|
||||||
spyOn(component, 'isSearchBarActive').and.returnValue(true);
|
spyOn(component, 'isSearchBarActive').and.returnValue(true);
|
||||||
spyOn(searchService, 'search').and.returnValue(Observable.of(results));
|
spyOn(searchService, 'search').and.returnValue(Observable.of(results));
|
||||||
|
|
||||||
@@ -108,10 +109,7 @@ describe('SearchControlComponent', () => {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
it('should NOT update FAYT term when user inputs an empty string as search term ', async(() => {
|
it('should NOT update FAYT term when user inputs an empty string as search term ', async(() => {
|
||||||
let inputDebugElement = debugElement.query(By.css('#adf-control-input'));
|
typeWordIntoSearchInput('');
|
||||||
inputDebugElement.nativeElement.value = '';
|
|
||||||
inputDebugElement.nativeElement.focus();
|
|
||||||
inputDebugElement.nativeElement.dispatchEvent(new Event('input'));
|
|
||||||
spyOn(component, 'isSearchBarActive').and.returnValue(true);
|
spyOn(component, 'isSearchBarActive').and.returnValue(true);
|
||||||
spyOn(searchService, 'search').and.returnValue(Observable.of(results));
|
spyOn(searchService, 'search').and.returnValue(Observable.of(results));
|
||||||
|
|
||||||
@@ -126,10 +124,7 @@ describe('SearchControlComponent', () => {
|
|||||||
component.searchChange.subscribe(value => {
|
component.searchChange.subscribe(value => {
|
||||||
expect(value).toBe('cu');
|
expect(value).toBe('cu');
|
||||||
});
|
});
|
||||||
let inputDebugElement = debugElement.query(By.css('#adf-control-input'));
|
typeWordIntoSearchInput('cu');
|
||||||
inputDebugElement.nativeElement.value = 'cu';
|
|
||||||
inputDebugElement.nativeElement.focus();
|
|
||||||
inputDebugElement.nativeElement.dispatchEvent(new Event('input'));
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
@@ -188,9 +183,7 @@ describe('SearchControlComponent', () => {
|
|||||||
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
let inputDebugElement = debugElement.query(By.css('#adf-control-input'));
|
let inputDebugElement = debugElement.query(By.css('#adf-control-input'));
|
||||||
inputDebugElement.nativeElement.value = 'TEST';
|
typeWordIntoSearchInput('TEST');
|
||||||
inputDebugElement.nativeElement.focus();
|
|
||||||
inputDebugElement.nativeElement.dispatchEvent(new Event('input'));
|
|
||||||
let enterKeyEvent: any = new Event('keyup');
|
let enterKeyEvent: any = new Event('keyup');
|
||||||
enterKeyEvent.keyCode = '13';
|
enterKeyEvent.keyCode = '13';
|
||||||
inputDebugElement.nativeElement.dispatchEvent(enterKeyEvent);
|
inputDebugElement.nativeElement.dispatchEvent(enterKeyEvent);
|
||||||
@@ -209,10 +202,7 @@ describe('SearchControlComponent', () => {
|
|||||||
spyOn(searchService, 'search').and.returnValue(Observable.of(results));
|
spyOn(searchService, 'search').and.returnValue(Observable.of(results));
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
let inputDebugElement = debugElement.query(By.css('#adf-control-input'));
|
typeWordIntoSearchInput('TEST');
|
||||||
inputDebugElement.nativeElement.value = 'TEST';
|
|
||||||
inputDebugElement.nativeElement.focus();
|
|
||||||
inputDebugElement.nativeElement.dispatchEvent(new Event('input'));
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
fixture.whenStable().then(() => {
|
fixture.whenStable().then(() => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
@@ -227,10 +217,7 @@ describe('SearchControlComponent', () => {
|
|||||||
spyOn(searchService, 'search').and.returnValue(Observable.of(noResult));
|
spyOn(searchService, 'search').and.returnValue(Observable.of(noResult));
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
let inputDebugElement = debugElement.query(By.css('#adf-control-input'));
|
typeWordIntoSearchInput('NO RES');
|
||||||
inputDebugElement.nativeElement.value = 'NO RES';
|
|
||||||
inputDebugElement.nativeElement.focus();
|
|
||||||
inputDebugElement.nativeElement.dispatchEvent(new Event('input'));
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
fixture.whenStable().then(() => {
|
fixture.whenStable().then(() => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
@@ -245,9 +232,7 @@ describe('SearchControlComponent', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
let inputDebugElement = debugElement.query(By.css('#adf-control-input'));
|
let inputDebugElement = debugElement.query(By.css('#adf-control-input'));
|
||||||
inputDebugElement.nativeElement.value = 'NO RES';
|
typeWordIntoSearchInput('NO RES');
|
||||||
inputDebugElement.nativeElement.focus();
|
|
||||||
inputDebugElement.nativeElement.dispatchEvent(new Event('input'));
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
fixture.whenStable().then(() => {
|
fixture.whenStable().then(() => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
@@ -268,9 +253,7 @@ describe('SearchControlComponent', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
let inputDebugElement = debugElement.query(By.css('#adf-control-input'));
|
let inputDebugElement = debugElement.query(By.css('#adf-control-input'));
|
||||||
inputDebugElement.nativeElement.value = 'TEST';
|
typeWordIntoSearchInput('TEST');
|
||||||
inputDebugElement.nativeElement.focus();
|
|
||||||
inputDebugElement.nativeElement.dispatchEvent(new Event('input'));
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
fixture.whenStable().then(() => {
|
fixture.whenStable().then(() => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
@@ -290,9 +273,7 @@ describe('SearchControlComponent', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
let inputDebugElement = debugElement.query(By.css('#adf-control-input'));
|
let inputDebugElement = debugElement.query(By.css('#adf-control-input'));
|
||||||
inputDebugElement.nativeElement.value = 'TEST';
|
typeWordIntoSearchInput('TEST');
|
||||||
inputDebugElement.nativeElement.focus();
|
|
||||||
inputDebugElement.nativeElement.dispatchEvent(new Event('input'));
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
fixture.whenStable().then(() => {
|
fixture.whenStable().then(() => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
@@ -315,9 +296,7 @@ describe('SearchControlComponent', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
let inputDebugElement = debugElement.query(By.css('#adf-control-input'));
|
let inputDebugElement = debugElement.query(By.css('#adf-control-input'));
|
||||||
inputDebugElement.nativeElement.value = 'TEST';
|
typeWordIntoSearchInput('TEST');
|
||||||
inputDebugElement.nativeElement.focus();
|
|
||||||
inputDebugElement.nativeElement.dispatchEvent(new Event('input'));
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
fixture.whenStable().then(() => {
|
fixture.whenStable().then(() => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
@@ -356,15 +335,75 @@ describe('SearchControlComponent', () => {
|
|||||||
component.liveSearchEnabled = false;
|
component.liveSearchEnabled = false;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
let inputDebugElement = debugElement.query(By.css('#adf-control-input'));
|
typeWordIntoSearchInput('TEST');
|
||||||
inputDebugElement.nativeElement.value = 'TEST';
|
|
||||||
inputDebugElement.nativeElement.focus();
|
|
||||||
inputDebugElement.nativeElement.dispatchEvent(new Event('input'));
|
|
||||||
fixture.whenStable().then(() => {
|
fixture.whenStable().then(() => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(element.querySelector('#autocomplete-search-result-list')).toBeNull();
|
expect(element.querySelector('#autocomplete-search-result-list')).toBeNull();
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
it('should select the first item on autocomplete list when ARROW DOWN is pressed on input', async(() => {
|
||||||
|
spyOn(searchService, 'search').and.returnValue(Observable.of(results));
|
||||||
|
fixture.detectChanges();
|
||||||
|
typeWordIntoSearchInput('TEST');
|
||||||
|
let inputDebugElement = debugElement.query(By.css('#adf-control-input'));
|
||||||
|
|
||||||
|
fixture.whenStable().then(() => {
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(element.querySelector('#autocomplete-search-result-list')).not.toBeNull();
|
||||||
|
|
||||||
|
inputDebugElement.triggerEventHandler('keyup.arrowdown', {});
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(document.activeElement.id).toBe('result_option_0');
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should select the second item on autocomplete list when ARROW DOWN is pressed on list', async(() => {
|
||||||
|
spyOn(searchService, 'search').and.returnValue(Observable.of(results));
|
||||||
|
fixture.detectChanges();
|
||||||
|
let inputDebugElement = debugElement.query(By.css('#adf-control-input'));
|
||||||
|
typeWordIntoSearchInput('TEST');
|
||||||
|
fixture.detectChanges();
|
||||||
|
fixture.whenStable().then(() => {
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(element.querySelector('#autocomplete-search-result-list')).not.toBeNull();
|
||||||
|
|
||||||
|
inputDebugElement.triggerEventHandler('keyup.arrowdown', {});
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(document.activeElement.id).toBe('result_option_0');
|
||||||
|
|
||||||
|
let firstElement = debugElement.query(By.css('#result_option_0'));
|
||||||
|
firstElement.triggerEventHandler('keyup.arrowdown', { target : firstElement.nativeElement});
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(document.activeElement.id).toBe('result_option_1');
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should focus the input search when ARROW UP is pressed on the first list item', async(() => {
|
||||||
|
spyOn(searchService, 'search').and.returnValue(Observable.of(results));
|
||||||
|
fixture.detectChanges();
|
||||||
|
let inputDebugElement = debugElement.query(By.css('#adf-control-input'));
|
||||||
|
typeWordIntoSearchInput('TEST');
|
||||||
|
fixture.detectChanges();
|
||||||
|
fixture.whenStable().then(() => {
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(element.querySelector('#autocomplete-search-result-list')).not.toBeNull();
|
||||||
|
|
||||||
|
inputDebugElement.triggerEventHandler('keyup.arrowdown', {});
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(document.activeElement.id).toBe('result_option_0');
|
||||||
|
|
||||||
|
let firstElement = debugElement.query(By.css('#result_option_0'));
|
||||||
|
firstElement.triggerEventHandler('keyup.arrowup', { target : firstElement.nativeElement});
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
fixture.whenStable().then(() => {
|
||||||
|
fixture.detectChanges();
|
||||||
|
expect(document.activeElement.id).toBe('adf-control-input');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('search button', () => {
|
describe('search button', () => {
|
||||||
@@ -434,10 +473,7 @@ describe('SearchControlComponent', () => {
|
|||||||
expect(item.entry.id).toBe('123');
|
expect(item.entry.id).toBe('123');
|
||||||
});
|
});
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
let inputDebugElement = debugElement.query(By.css('#adf-control-input'));
|
typeWordIntoSearchInput('TEST');
|
||||||
inputDebugElement.nativeElement.value = 'TEST';
|
|
||||||
inputDebugElement.nativeElement.focus();
|
|
||||||
inputDebugElement.nativeElement.dispatchEvent(new Event('input'));
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
fixture.whenStable().then(() => {
|
fixture.whenStable().then(() => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
@@ -456,10 +492,7 @@ describe('SearchControlComponent', () => {
|
|||||||
});
|
});
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
let inputDebugElement = debugElement.query(By.css('#adf-control-input'));
|
typeWordIntoSearchInput('TEST');
|
||||||
inputDebugElement.nativeElement.value = 'TEST';
|
|
||||||
inputDebugElement.nativeElement.focus();
|
|
||||||
inputDebugElement.nativeElement.dispatchEvent(new Event('input'));
|
|
||||||
|
|
||||||
fixture.whenStable().then(() => {
|
fixture.whenStable().then(() => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
@@ -476,10 +509,7 @@ describe('SearchControlComponent', () => {
|
|||||||
expect(component.searchTerm).toBe('TEST');
|
expect(component.searchTerm).toBe('TEST');
|
||||||
});
|
});
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
let inputDebugElement = debugElement.query(By.css('#adf-control-input'));
|
typeWordIntoSearchInput('TEST');
|
||||||
inputDebugElement.nativeElement.value = 'TEST';
|
|
||||||
inputDebugElement.nativeElement.focus();
|
|
||||||
inputDebugElement.nativeElement.dispatchEvent(new Event('input'));
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
fixture.whenStable().then(() => {
|
fixture.whenStable().then(() => {
|
||||||
|
@@ -17,11 +17,13 @@
|
|||||||
|
|
||||||
import { AuthenticationService, ThumbnailService } from '@alfresco/adf-core';
|
import { AuthenticationService, ThumbnailService } from '@alfresco/adf-core';
|
||||||
import { animate, state, style, transition, trigger } from '@angular/animations';
|
import { animate, state, style, transition, trigger } from '@angular/animations';
|
||||||
import { Component, EventEmitter, Input, OnDestroy, OnInit, Output, ViewEncapsulation } from '@angular/core';
|
import { Component, EventEmitter, Input, OnDestroy, OnInit, Output,
|
||||||
|
QueryList, ViewEncapsulation, ViewChild, ViewChildren, ElementRef } from '@angular/core';
|
||||||
import { MinimalNodeEntity, QueryBody } from 'alfresco-js-api';
|
import { MinimalNodeEntity, QueryBody } from 'alfresco-js-api';
|
||||||
import { Observable } from 'rxjs/Observable';
|
import { Observable } from 'rxjs/Observable';
|
||||||
import { Subject } from 'rxjs/Subject';
|
import { Subject } from 'rxjs/Subject';
|
||||||
import 'rxjs/add/operator/distinctUntilChanged';
|
import { SearchComponent } from './search.component';
|
||||||
|
import { MatListItem } from '@angular/material';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'adf-search-control',
|
selector: 'adf-search-control',
|
||||||
@@ -73,6 +75,15 @@ export class SearchControlComponent implements OnInit, OnDestroy {
|
|||||||
@Output()
|
@Output()
|
||||||
optionClicked: EventEmitter<any> = new EventEmitter();
|
optionClicked: EventEmitter<any> = new EventEmitter();
|
||||||
|
|
||||||
|
@ViewChild(SearchComponent)
|
||||||
|
searchAutocomplete: SearchComponent;
|
||||||
|
|
||||||
|
@ViewChild('inputSearch')
|
||||||
|
inputSearch: ElementRef;
|
||||||
|
|
||||||
|
@ViewChildren(MatListItem)
|
||||||
|
private listResultElement: QueryList<MatListItem>;
|
||||||
|
|
||||||
searchTerm: string = '';
|
searchTerm: string = '';
|
||||||
subscriptAnimationState: string;
|
subscriptAnimationState: string;
|
||||||
|
|
||||||
@@ -88,6 +99,10 @@ export class SearchControlComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
if (this.subscriptAnimationState === 'inactive') {
|
if (this.subscriptAnimationState === 'inactive') {
|
||||||
this.searchTerm = '';
|
this.searchTerm = '';
|
||||||
|
this.searchAutocomplete.resetResults();
|
||||||
|
if ( document.activeElement.id === this.inputSearch.nativeElement.id) {
|
||||||
|
this.inputSearch.nativeElement.blur();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -165,15 +180,39 @@ export class SearchControlComponent implements OnInit, OnDestroy {
|
|||||||
this.focusSubject.next($event);
|
this.focusSubject.next($event);
|
||||||
}
|
}
|
||||||
|
|
||||||
activateToolbar($event) {
|
activateToolbar() {
|
||||||
if (!this.isSearchBarActive()) {
|
if (!this.isSearchBarActive()) {
|
||||||
this.toggleSearchBar();
|
this.toggleSearchBar();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
selectFirstResult() {
|
||||||
|
if ( this.listResultElement && this.listResultElement.length > 0) {
|
||||||
|
let firstElement: MatListItem = <MatListItem> this.listResultElement.first;
|
||||||
|
firstElement._getHostElement().focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onRowArrowDown($event: KeyboardEvent): void {
|
||||||
|
let nextElement: any = this.getNextElementSibling(<Element> $event.target);
|
||||||
|
if (nextElement) {
|
||||||
|
nextElement.focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onRowArrowUp($event: KeyboardEvent): void {
|
||||||
|
let previousElement: any = this.getPreviousElementSibling(<Element> $event.target);
|
||||||
|
if (previousElement) {
|
||||||
|
previousElement.focus();
|
||||||
|
}else {
|
||||||
|
this.inputSearch.nativeElement.focus();
|
||||||
|
this.focusSubject.next(new FocusEvent('focus'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private setupFocusEventHandlers() {
|
private setupFocusEventHandlers() {
|
||||||
let focusEvents: Observable<FocusEvent> = this.focusSubject.asObservable()
|
let focusEvents: Observable<FocusEvent> = this.focusSubject.asObservable()
|
||||||
.distinctUntilChanged().debounceTime(50);
|
.debounceTime(50);
|
||||||
focusEvents.filter(($event: any) => {
|
focusEvents.filter(($event: any) => {
|
||||||
return this.isSearchBarActive() && ($event.type === 'blur' || $event.type === 'focusout');
|
return this.isSearchBarActive() && ($event.type === 'blur' || $event.type === 'focusout');
|
||||||
}).subscribe(() => {
|
}).subscribe(() => {
|
||||||
@@ -181,4 +220,12 @@ export class SearchControlComponent implements OnInit, OnDestroy {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private getNextElementSibling(node: Element): Element {
|
||||||
|
return node.nextElementSibling;
|
||||||
|
}
|
||||||
|
|
||||||
|
private getPreviousElementSibling(node: Element): Element {
|
||||||
|
return node.previousElementSibling;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { DOWN_ARROW, ENTER, ESCAPE, UP_ARROW } from '@angular/cdk/keycodes';
|
import { ENTER, ESCAPE } from '@angular/cdk/keycodes';
|
||||||
import {
|
import {
|
||||||
ChangeDetectorRef,
|
ChangeDetectorRef,
|
||||||
Directive,
|
Directive,
|
||||||
@@ -36,10 +36,6 @@ import { Subject } from 'rxjs/Subject';
|
|||||||
import { Subscription } from 'rxjs/Subscription';
|
import { Subscription } from 'rxjs/Subscription';
|
||||||
import { SearchComponent } from './search.component';
|
import { SearchComponent } from './search.component';
|
||||||
|
|
||||||
export const AUTOCOMPLETE_OPTION_HEIGHT = 48;
|
|
||||||
|
|
||||||
export const AUTOCOMPLETE_PANEL_HEIGHT = 256;
|
|
||||||
|
|
||||||
export const SEARCH_AUTOCOMPLETE_VALUE_ACCESSOR: any = {
|
export const SEARCH_AUTOCOMPLETE_VALUE_ACCESSOR: any = {
|
||||||
provide: NG_VALUE_ACCESSOR,
|
provide: NG_VALUE_ACCESSOR,
|
||||||
useExisting: forwardRef(() => SearchTriggerDirective),
|
useExisting: forwardRef(() => SearchTriggerDirective),
|
||||||
@@ -150,14 +146,8 @@ export class SearchTriggerDirective implements ControlValueAccessor, OnDestroy {
|
|||||||
} else if (keyCode === ENTER) {
|
} else if (keyCode === ENTER) {
|
||||||
this.escapeEventStream.next();
|
this.escapeEventStream.next();
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}else {
|
|
||||||
let isArrowKey = keyCode === UP_ARROW || keyCode === DOWN_ARROW;
|
|
||||||
if ( isArrowKey ) {
|
|
||||||
if ( !this.panelOpen ) {
|
|
||||||
this.openPanel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
handleInput(event: KeyboardEvent): void {
|
handleInput(event: KeyboardEvent): void {
|
||||||
@@ -168,6 +158,7 @@ export class SearchTriggerDirective implements ControlValueAccessor, OnDestroy {
|
|||||||
this.searchPanel.keyPressedStream.next(inputValue);
|
this.searchPanel.keyPressedStream.next(inputValue);
|
||||||
this.openPanel();
|
this.openPanel();
|
||||||
} else {
|
} else {
|
||||||
|
this.searchPanel.resetResults();
|
||||||
this.closePanel();
|
this.closePanel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user