mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-31 17:38:48 +00:00
New implementation of focus/blur event management using Obserable
Refs #371
This commit is contained in:
@@ -0,0 +1,76 @@
|
|||||||
|
/*!
|
||||||
|
* @license
|
||||||
|
* Copyright 2016 Alfresco Software, Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export var result = {
|
||||||
|
list: {
|
||||||
|
entries: [
|
||||||
|
{
|
||||||
|
entry: {
|
||||||
|
id: '123',
|
||||||
|
name: 'MyDoc',
|
||||||
|
isFile : true,
|
||||||
|
content: {
|
||||||
|
mimeType: 'text/plain'
|
||||||
|
},
|
||||||
|
createdByUser: {
|
||||||
|
displayName: 'John Doe'
|
||||||
|
},
|
||||||
|
modifiedByUser: {
|
||||||
|
displayName: 'John Doe'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export var folderResult = {
|
||||||
|
list: {
|
||||||
|
entries: [
|
||||||
|
{
|
||||||
|
entry: {
|
||||||
|
id: '123',
|
||||||
|
name: 'MyFolder',
|
||||||
|
isFile : false,
|
||||||
|
isFolder : true,
|
||||||
|
createdByUser: {
|
||||||
|
displayName: 'John Doe'
|
||||||
|
},
|
||||||
|
modifiedByUser: {
|
||||||
|
displayName: 'John Doe'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export var noResult = {
|
||||||
|
list: {
|
||||||
|
entries: []
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export var errorJson = {
|
||||||
|
error: {
|
||||||
|
errorKey: 'Search failed',
|
||||||
|
statusCode: 400,
|
||||||
|
briefSummary: '08220082 search failed',
|
||||||
|
stackTrace: 'For security reasons the stack trace is no longer displayed, but the property is kept for previous versions.',
|
||||||
|
descriptionURL: 'https://api-explorer.alfresco.com'
|
||||||
|
}
|
||||||
|
};
|
@@ -1,7 +1,7 @@
|
|||||||
<table data-automation-id="autocomplete_results" *ngIf="results && results.length && searchTerm"
|
<table data-automation-id="autocomplete_results" *ngIf="results && results.length && searchTerm"
|
||||||
class="mdl-data-table mdl-js-data-table mdl-shadow--2dp full-width">
|
class="mdl-data-table mdl-js-data-table mdl-shadow--2dp full-width">
|
||||||
<tbody (focusout)="onFocusOut()">
|
<tbody>
|
||||||
<tr id="result_row_{{idx}}" *ngFor="let result of results; let idx = index" tabindex="0" (blur)="onRowBlur(result)" (focus)="onRowFocus(result)" (click)="onItemClick(result, $event)" (keyup.enter)="onRowEnter(result, $event)"
|
<tr id="result_row_{{idx}}" *ngFor="let result of results; let idx = index" tabindex="0" (blur)="onRowBlur($event)" (focus)="onRowFocus($event)" (click)="onItemClick(result, $event)" (keyup.enter)="onRowEnter(result, $event)"
|
||||||
attr.data-automation-id="autocomplete_result_for_{{result.entry.name}}">
|
attr.data-automation-id="autocomplete_result_for_{{result.entry.name}}">
|
||||||
<td class="img-td"><img src="{{getMimeTypeIcon(result)}}" alt="{{getMimeTypeKey(result)|translate}}"/></td>
|
<td class="img-td"><img src="{{getMimeTypeIcon(result)}}" alt="{{getMimeTypeKey(result)|translate}}"/></td>
|
||||||
<td>
|
<td>
|
||||||
|
@@ -19,6 +19,7 @@ import { ComponentFixture, TestBed, async } from '@angular/core/testing';
|
|||||||
import { AlfrescoSearchAutocompleteComponent } from './alfresco-search-autocomplete.component';
|
import { AlfrescoSearchAutocompleteComponent } from './alfresco-search-autocomplete.component';
|
||||||
import { AlfrescoThumbnailService } from './../services/alfresco-thumbnail.service';
|
import { AlfrescoThumbnailService } from './../services/alfresco-thumbnail.service';
|
||||||
import { TranslationMock } from './../assets/translation.service.mock';
|
import { TranslationMock } from './../assets/translation.service.mock';
|
||||||
|
import { result, folderResult, noResult, errorJson } from './../assets/alfresco-search.component.mock';
|
||||||
import { AlfrescoSearchService } from '../services/alfresco-search.service';
|
import { AlfrescoSearchService } from '../services/alfresco-search.service';
|
||||||
import {
|
import {
|
||||||
AlfrescoApiService,
|
AlfrescoApiService,
|
||||||
@@ -34,66 +35,6 @@ describe('AlfrescoSearchAutocompleteComponent', () => {
|
|||||||
let fixture: ComponentFixture<AlfrescoSearchAutocompleteComponent>, element: HTMLElement;
|
let fixture: ComponentFixture<AlfrescoSearchAutocompleteComponent>, element: HTMLElement;
|
||||||
let component: AlfrescoSearchAutocompleteComponent;
|
let component: AlfrescoSearchAutocompleteComponent;
|
||||||
|
|
||||||
let result = {
|
|
||||||
list: {
|
|
||||||
entries: [
|
|
||||||
{
|
|
||||||
entry: {
|
|
||||||
id: '123',
|
|
||||||
name: 'MyDoc',
|
|
||||||
isFile : true,
|
|
||||||
content: {
|
|
||||||
mimeType: 'text/plain'
|
|
||||||
},
|
|
||||||
createdByUser: {
|
|
||||||
displayName: 'John Doe'
|
|
||||||
},
|
|
||||||
modifiedByUser: {
|
|
||||||
displayName: 'John Doe'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let folderResult = {
|
|
||||||
list: {
|
|
||||||
entries: [
|
|
||||||
{
|
|
||||||
entry: {
|
|
||||||
id: '123',
|
|
||||||
name: 'MyFolder',
|
|
||||||
isFile : false,
|
|
||||||
isFolder : true,
|
|
||||||
createdByUser: {
|
|
||||||
displayName: 'John Doe'
|
|
||||||
},
|
|
||||||
modifiedByUser: {
|
|
||||||
displayName: 'John Doe'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let noResult = {
|
|
||||||
list: {
|
|
||||||
entries: []
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let errorJson = {
|
|
||||||
error: {
|
|
||||||
errorKey: 'Search failed',
|
|
||||||
statusCode: 400,
|
|
||||||
briefSummary: '08220082 search failed',
|
|
||||||
stackTrace: 'For security reasons the stack trace is no longer displayed, but the property is kept for previous versions.',
|
|
||||||
descriptionURL: 'https://api-explorer.alfresco.com'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
beforeEach(async(() => {
|
beforeEach(async(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [
|
imports: [
|
||||||
@@ -286,4 +227,67 @@ describe('AlfrescoSearchAutocompleteComponent', () => {
|
|||||||
component.ngOnChanges({searchTerm: { currentValue: 'searchTerm', previousValue: ''}});
|
component.ngOnChanges({searchTerm: { currentValue: 'searchTerm', previousValue: ''}});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should emit preview when enter key pressed when a file item is in focus', (done) => {
|
||||||
|
|
||||||
|
let searchService = fixture.debugElement.injector.get(AlfrescoSearchService);
|
||||||
|
spyOn(searchService, 'getSearchNodesPromise')
|
||||||
|
.and.returnValue(Promise.resolve(result));
|
||||||
|
|
||||||
|
component.resultsEmitter.subscribe(x => {
|
||||||
|
fixture.detectChanges();
|
||||||
|
(<any> element.querySelector('#result_row_0')).dispatchEvent(new KeyboardEvent('keyup', {
|
||||||
|
key: 'Enter'
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
component.searchTerm = 'searchTerm';
|
||||||
|
component.ngOnChanges({searchTerm: { currentValue: 'searchTerm', previousValue: ''}});
|
||||||
|
|
||||||
|
component.preview.subscribe(e => {
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should emit a focus event when a result comes into focus', (done) => {
|
||||||
|
|
||||||
|
let searchService = fixture.debugElement.injector.get(AlfrescoSearchService);
|
||||||
|
spyOn(searchService, 'getSearchNodesPromise')
|
||||||
|
.and.returnValue(Promise.resolve(result));
|
||||||
|
|
||||||
|
component.resultsEmitter.subscribe(x => {
|
||||||
|
fixture.detectChanges();
|
||||||
|
(<any> element.querySelector('#result_row_0')).dispatchEvent(new FocusEvent('focus'));
|
||||||
|
});
|
||||||
|
|
||||||
|
component.searchTerm = 'searchTerm';
|
||||||
|
component.ngOnChanges({searchTerm: { currentValue: 'searchTerm', previousValue: ''}});
|
||||||
|
|
||||||
|
component.focusEmitter.subscribe((e: FocusEvent) => {
|
||||||
|
expect(e).not.toBeNull();
|
||||||
|
expect(e.type).toBe('focus');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should emit a focus event when a result loses focus', (done) => {
|
||||||
|
|
||||||
|
let searchService = fixture.debugElement.injector.get(AlfrescoSearchService);
|
||||||
|
spyOn(searchService, 'getSearchNodesPromise')
|
||||||
|
.and.returnValue(Promise.resolve(result));
|
||||||
|
|
||||||
|
component.resultsEmitter.subscribe(x => {
|
||||||
|
fixture.detectChanges();
|
||||||
|
(<any> element.querySelector('#result_row_0')).dispatchEvent(new FocusEvent('blur'));
|
||||||
|
});
|
||||||
|
|
||||||
|
component.searchTerm = 'searchTerm';
|
||||||
|
component.ngOnChanges({searchTerm: { currentValue: 'searchTerm', previousValue: ''}});
|
||||||
|
|
||||||
|
component.focusEmitter.subscribe((e: FocusEvent) => {
|
||||||
|
expect(e).not.toBeNull();
|
||||||
|
expect(e.type).toBe('blur');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@@ -44,7 +44,7 @@ export class AlfrescoSearchAutocompleteComponent implements OnInit, OnChanges {
|
|||||||
preview: EventEmitter<any> = new EventEmitter();
|
preview: EventEmitter<any> = new EventEmitter();
|
||||||
|
|
||||||
@Output()
|
@Output()
|
||||||
blurEmitter: EventEmitter<any> = new EventEmitter();
|
focusEmitter: EventEmitter<FocusEvent> = new EventEmitter<FocusEvent>();
|
||||||
|
|
||||||
@Output()
|
@Output()
|
||||||
resultsEmitter = new EventEmitter();
|
resultsEmitter = new EventEmitter();
|
||||||
@@ -132,19 +132,12 @@ export class AlfrescoSearchAutocompleteComponent implements OnInit, OnChanges {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onRowBlur(node): void {
|
onRowFocus($event: FocusEvent): void {
|
||||||
window.setTimeout(() => {
|
this.focusEmitter.emit($event);
|
||||||
let focusedEl = document.activeElement;
|
|
||||||
if (focusedEl && focusedEl.id && focusedEl.id.indexOf('result_row_') === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.blurEmitter.emit(node);
|
|
||||||
}, 100);
|
|
||||||
console.log('row blur', node);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onRowFocus(node): void {
|
onRowBlur($event: FocusEvent): void {
|
||||||
console.log('row focus', node);
|
this.focusEmitter.emit($event);
|
||||||
}
|
}
|
||||||
|
|
||||||
onRowEnter(node): void {
|
onRowEnter(node): void {
|
||||||
@@ -157,8 +150,4 @@ export class AlfrescoSearchAutocompleteComponent implements OnInit, OnChanges {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onFocusOut(): void {
|
|
||||||
console.log('onfocusout');
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -24,4 +24,5 @@
|
|||||||
</form>
|
</form>
|
||||||
<alfresco-search-autocomplete *ngIf="autocompleteEnabled"
|
<alfresco-search-autocomplete *ngIf="autocompleteEnabled"
|
||||||
[searchTerm]="autocompleteSearchTerm" [ngClass]="{active: searchActive, valid: searchValid}"
|
[searchTerm]="autocompleteSearchTerm" [ngClass]="{active: searchActive, valid: searchValid}"
|
||||||
(preview)="onFileClicked($event)" (blurEmitter)="onAutoCompleteBlur($event)"></alfresco-search-autocomplete>
|
(preview)="onFileClicked($event)"
|
||||||
|
(focusEmitter)="onAutoCompleteFocus($event)"></alfresco-search-autocomplete>
|
||||||
|
@@ -20,6 +20,7 @@ import { AlfrescoSearchControlComponent } from './alfresco-search-control.compon
|
|||||||
import { AlfrescoSearchAutocompleteComponent } from './alfresco-search-autocomplete.component';
|
import { AlfrescoSearchAutocompleteComponent } from './alfresco-search-autocomplete.component';
|
||||||
import { AlfrescoThumbnailService } from './../services/alfresco-thumbnail.service';
|
import { AlfrescoThumbnailService } from './../services/alfresco-thumbnail.service';
|
||||||
import { TranslationMock } from './../assets/translation.service.mock';
|
import { TranslationMock } from './../assets/translation.service.mock';
|
||||||
|
import { result } from './../assets/alfresco-search.component.mock';
|
||||||
import {
|
import {
|
||||||
AlfrescoSettingsService,
|
AlfrescoSettingsService,
|
||||||
AlfrescoApiService,
|
AlfrescoApiService,
|
||||||
@@ -150,24 +151,45 @@ describe('AlfrescoSearchControlComponent', () => {
|
|||||||
expect(autocomplete.classList.contains('active')).toBe(false);
|
expect(autocomplete.classList.contains('active')).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should make find-as-you-type control visible when search box has focus', () => {
|
it('should make find-as-you-type control visible when search box has focus', (done) => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
inputEl.dispatchEvent(new Event('focus'));
|
inputEl.dispatchEvent(new FocusEvent('focus'));
|
||||||
|
window.setTimeout(() => { // wait for debounce() to complete
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
let autocomplete: Element = element.querySelector('alfresco-search-autocomplete');
|
let autocomplete: Element = element.querySelector('alfresco-search-autocomplete');
|
||||||
expect(autocomplete.classList.contains('active')).toBe(true);
|
expect(autocomplete.classList.contains('active')).toBe(true);
|
||||||
|
done();
|
||||||
|
}, 100);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should hide find-as-you-type results when the search box loses focus', (done) => {
|
it('should hide find-as-you-type results when the search box loses focus', (done) => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
inputEl.dispatchEvent(new Event('focus'));
|
inputEl.dispatchEvent(new FocusEvent('focus'));
|
||||||
inputEl.dispatchEvent(new Event('blur'));
|
inputEl.dispatchEvent(new FocusEvent('blur'));
|
||||||
window.setTimeout(() => {
|
window.setTimeout(() => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
let autocomplete: Element = element.querySelector('alfresco-search-autocomplete');
|
let autocomplete: Element = element.querySelector('alfresco-search-autocomplete');
|
||||||
expect(autocomplete.classList.contains('active')).toBe(false);
|
expect(autocomplete.classList.contains('active')).toBe(false);
|
||||||
done();
|
done();
|
||||||
}, 250);
|
}, 100);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should keep find-as-you-type control visible when user tabs into results', (done) => {
|
||||||
|
let searchService = fixture.debugElement.injector.get(AlfrescoSearchService);
|
||||||
|
spyOn(searchService, 'getSearchNodesPromise')
|
||||||
|
.and.returnValue(Promise.resolve(result));
|
||||||
|
|
||||||
|
fixture.detectChanges();
|
||||||
|
inputEl.dispatchEvent(new FocusEvent('focus'));
|
||||||
|
fixture.detectChanges();
|
||||||
|
inputEl.dispatchEvent(new FocusEvent('blur'));
|
||||||
|
component.onAutoCompleteFocus(new FocusEvent('focus'));
|
||||||
|
window.setTimeout(() => { // wait for debounce() to complete
|
||||||
|
fixture.detectChanges();
|
||||||
|
let autocomplete: Element = element.querySelector('alfresco-search-autocomplete');
|
||||||
|
expect(autocomplete.classList.contains('active')).toBe(true);
|
||||||
|
done();
|
||||||
|
}, 100);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should hide find-as-you-type results when escape key pressed', () => {
|
it('should hide find-as-you-type results when escape key pressed', () => {
|
||||||
@@ -239,32 +261,41 @@ describe('AlfrescoSearchControlComponent', () => {
|
|||||||
|
|
||||||
describe('component focus', () => {
|
describe('component focus', () => {
|
||||||
|
|
||||||
it('should fire an event when the search box receives focus', () => {
|
it('should fire an event when the search box receives focus', (done) => {
|
||||||
spyOn(component.expand, 'emit');
|
spyOn(component.expand, 'emit');
|
||||||
let inputEl: HTMLElement = element.querySelector('input');
|
let inputEl: HTMLElement = element.querySelector('input');
|
||||||
inputEl.dispatchEvent(new Event('focus'));
|
inputEl.dispatchEvent(new FocusEvent('focus'));
|
||||||
|
window.setTimeout(() => {
|
||||||
expect(component.expand.emit).toHaveBeenCalledWith({
|
expect(component.expand.emit).toHaveBeenCalledWith({
|
||||||
expanded: true
|
expanded: true
|
||||||
});
|
});
|
||||||
|
done();
|
||||||
|
}, 100);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fire an event when the search box loses focus', () => {
|
it('should fire an event when the search box loses focus', (done) => {
|
||||||
spyOn(component.expand, 'emit');
|
spyOn(component.expand, 'emit');
|
||||||
let inputEl: HTMLElement = element.querySelector('input');
|
let inputEl: HTMLElement = element.querySelector('input');
|
||||||
inputEl.dispatchEvent(new Event('blur'));
|
inputEl.dispatchEvent(new FocusEvent('blur'));
|
||||||
|
window.setTimeout(() => {
|
||||||
expect(component.expand.emit).toHaveBeenCalledWith({
|
expect(component.expand.emit).toHaveBeenCalledWith({
|
||||||
expanded: false
|
expanded: false
|
||||||
});
|
});
|
||||||
|
done();
|
||||||
|
}, 100);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should NOT fire an event when the search box receives/loses focus but the component is not expandable',
|
it('should NOT fire an event when the search box receives/loses focus but the component is not expandable',
|
||||||
() => {
|
(done) => {
|
||||||
spyOn(component.expand, 'emit');
|
spyOn(component.expand, 'emit');
|
||||||
component.expandable = false;
|
component.expandable = false;
|
||||||
let inputEl: HTMLElement = element.querySelector('input');
|
let inputEl: HTMLElement = element.querySelector('input');
|
||||||
inputEl.dispatchEvent(new Event('focus'));
|
inputEl.dispatchEvent(new FocusEvent('focus'));
|
||||||
inputEl.dispatchEvent(new Event('blur'));
|
inputEl.dispatchEvent(new FocusEvent('blur'));
|
||||||
|
window.setTimeout(() => {
|
||||||
expect(component.expand.emit).not.toHaveBeenCalled();
|
expect(component.expand.emit).not.toHaveBeenCalled();
|
||||||
|
done();
|
||||||
|
}, 100);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@@ -16,9 +16,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { FormControl, Validators } from '@angular/forms';
|
import { FormControl, Validators } from '@angular/forms';
|
||||||
import { Component, Input, Output, OnInit, ElementRef, EventEmitter, ViewChild } from '@angular/core';
|
import { Component, Input, Output, OnInit, OnDestroy, ElementRef, EventEmitter, ViewChild } from '@angular/core';
|
||||||
import { AlfrescoTranslationService } from 'ng2-alfresco-core';
|
import { AlfrescoTranslationService } from 'ng2-alfresco-core';
|
||||||
import { SearchTermValidator } from './../forms/search-term-validator';
|
import { SearchTermValidator } from './../forms/search-term-validator';
|
||||||
|
import { Observable, Subject } from 'rxjs/Rx';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
moduleId: module.id,
|
moduleId: module.id,
|
||||||
@@ -26,7 +27,7 @@ import { SearchTermValidator } from './../forms/search-term-validator';
|
|||||||
templateUrl: './alfresco-search-control.component.html',
|
templateUrl: './alfresco-search-control.component.html',
|
||||||
styleUrls: ['./alfresco-search-control.component.css']
|
styleUrls: ['./alfresco-search-control.component.css']
|
||||||
})
|
})
|
||||||
export class AlfrescoSearchControlComponent implements OnInit {
|
export class AlfrescoSearchControlComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
searchTerm = '';
|
searchTerm = '';
|
||||||
@@ -66,6 +67,8 @@ export class AlfrescoSearchControlComponent implements OnInit {
|
|||||||
|
|
||||||
searchValid = false;
|
searchValid = false;
|
||||||
|
|
||||||
|
private focusSubject = new Subject<FocusEvent>();
|
||||||
|
|
||||||
constructor(private translate: AlfrescoTranslationService) {
|
constructor(private translate: AlfrescoTranslationService) {
|
||||||
|
|
||||||
this.searchControl = new FormControl(
|
this.searchControl = new FormControl(
|
||||||
@@ -80,9 +83,16 @@ export class AlfrescoSearchControlComponent implements OnInit {
|
|||||||
this.onSearchTermChange(value);
|
this.onSearchTermChange(value);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this.setupFocusEventHandlers();
|
||||||
|
|
||||||
this.translate.addTranslationFolder('node_modules/ng2-alfresco-search/dist/src');
|
this.translate.addTranslationFolder('node_modules/ng2-alfresco-search/dist/src');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
this.focusSubject.unsubscribe();
|
||||||
|
}
|
||||||
|
|
||||||
private onSearchTermChange(value: string): void {
|
private onSearchTermChange(value: string): void {
|
||||||
this.searchActive = true;
|
this.searchActive = true;
|
||||||
this.autocompleteSearchTerm = value;
|
this.autocompleteSearchTerm = value;
|
||||||
@@ -94,6 +104,20 @@ export class AlfrescoSearchControlComponent implements OnInit {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private setupFocusEventHandlers() {
|
||||||
|
let focusEvents: Observable<FocusEvent> = this.focusSubject.asObservable().debounceTime(50);
|
||||||
|
focusEvents.filter(($event: FocusEvent) => {
|
||||||
|
return $event.type === 'focusin' || $event.type === 'focus';
|
||||||
|
}).subscribe(($event) => {
|
||||||
|
this.onSearchFocus($event);
|
||||||
|
});
|
||||||
|
focusEvents.filter(($event: any) => {
|
||||||
|
return $event.type === 'focusout' || $event.type === 'blur';
|
||||||
|
}).subscribe(($event) => {
|
||||||
|
this.onSearchBlur($event);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
getTextFieldClassName(): string {
|
getTextFieldClassName(): string {
|
||||||
return 'mdl-textfield mdl-js-textfield' + (this.expandable ? ' mdl-textfield--expandable' : '');
|
return 'mdl-textfield mdl-js-textfield' + (this.expandable ? ' mdl-textfield--expandable' : '');
|
||||||
}
|
}
|
||||||
@@ -127,28 +151,30 @@ export class AlfrescoSearchControlComponent implements OnInit {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onFocus(): void {
|
onSearchFocus($event): void {
|
||||||
this.searchActive = true;
|
this.searchActive = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
onSearchBlur($event): void {
|
||||||
|
this.searchActive = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
onFocus($event): void {
|
||||||
if (this.expandable) {
|
if (this.expandable) {
|
||||||
this.expand.emit({
|
this.expand.emit({
|
||||||
expanded: true
|
expanded: true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
this.focusSubject.next($event);
|
||||||
}
|
}
|
||||||
|
|
||||||
onBlur(): void {
|
onBlur($event): void {
|
||||||
window.setTimeout(() => {
|
|
||||||
let focusedEl = document.activeElement;
|
|
||||||
if (focusedEl && focusedEl.id && focusedEl.id.indexOf('result_row_') === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.searchActive = false;
|
|
||||||
}, 200);
|
|
||||||
if (this.expandable && (this.searchControl.value === '' || this.searchControl.value === undefined)) {
|
if (this.expandable && (this.searchControl.value === '' || this.searchControl.value === undefined)) {
|
||||||
this.expand.emit({
|
this.expand.emit({
|
||||||
expanded: false
|
expanded: false
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
this.focusSubject.next($event);
|
||||||
}
|
}
|
||||||
|
|
||||||
onEscape(): void {
|
onEscape(): void {
|
||||||
@@ -159,8 +185,8 @@ export class AlfrescoSearchControlComponent implements OnInit {
|
|||||||
this.searchActive = true;
|
this.searchActive = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
onAutoCompleteBlur(): void {
|
onAutoCompleteFocus($event): void {
|
||||||
this.searchActive = false;
|
this.focusSubject.next($event);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user