mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-05-19 17:14:57 +00:00
#1091 - fix typeahead widget
This commit is contained in:
parent
29c5b61c00
commit
e114534bc5
@ -1,6 +1,6 @@
|
|||||||
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label typeahead-widget"
|
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label typeahead-widget"
|
||||||
[class.is-dirty]="value"
|
[class.is-dirty]="value"
|
||||||
[class.typeahead-widget__invalid]="!field.isValid" id="typehead-div">
|
[class.typeahead-widget__invalid]="!field.isValid" id="typehead-div" *ngIf="field.isVisible">
|
||||||
<input class="mdl-textfield__input"
|
<input class="mdl-textfield__input"
|
||||||
type="text"
|
type="text"
|
||||||
[attr.id]="field.id"
|
[attr.id]="field.id"
|
||||||
@ -14,6 +14,7 @@
|
|||||||
<div class="typeahead-autocomplete mdl-shadow--2dp" *ngIf="options.length > 0 && popupVisible">
|
<div class="typeahead-autocomplete mdl-shadow--2dp" *ngIf="options.length > 0 && popupVisible">
|
||||||
<ul>
|
<ul>
|
||||||
<li *ngFor="let item of options"
|
<li *ngFor="let item of options"
|
||||||
|
[attr.id]="field.id +'-'+item.id"
|
||||||
class="mdl-menu__item"
|
class="mdl-menu__item"
|
||||||
(click)="onItemClick(item, $event)">
|
(click)="onItemClick(item, $event)">
|
||||||
{{item.name}}
|
{{item.name}}
|
||||||
|
@ -21,16 +21,23 @@ import { FormService } from '../../../services/form.service';
|
|||||||
import { FormModel } from '../core/form.model';
|
import { FormModel } from '../core/form.model';
|
||||||
import { FormFieldModel } from '../core/form-field.model';
|
import { FormFieldModel } from '../core/form-field.model';
|
||||||
import { FormFieldOption } from '../core/form-field-option';
|
import { FormFieldOption } from '../core/form-field-option';
|
||||||
|
import { CoreModule } from 'ng2-alfresco-core';
|
||||||
|
import { ComponentFixture, TestBed, async } from '@angular/core/testing';
|
||||||
|
import { EcmModelService } from '../../../services/ecm-model.service';
|
||||||
|
import { WidgetVisibilityService } from '../../../services/widget-visibility.service';
|
||||||
|
import { FormFieldTypes } from '../core/form-field-types';
|
||||||
|
|
||||||
describe('TypeaheadWidget', () => {
|
describe('TypeaheadWidget', () => {
|
||||||
|
|
||||||
let formService: FormService;
|
let formService: FormService;
|
||||||
let widget: TypeaheadWidget;
|
let widget: TypeaheadWidget;
|
||||||
|
let visibilityService: WidgetVisibilityService;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
formService = new FormService(null, null);
|
formService = new FormService(null, null);
|
||||||
widget = new TypeaheadWidget(formService);
|
visibilityService = new WidgetVisibilityService(null, null, null);
|
||||||
widget.field = new FormFieldModel(new FormModel());
|
widget = new TypeaheadWidget(formService, visibilityService);
|
||||||
|
widget.field = new FormFieldModel(new FormModel({ taskId: 'task-id' }));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should request field values from service', () => {
|
it('should request field values from service', () => {
|
||||||
@ -53,7 +60,17 @@ describe('TypeaheadWidget', () => {
|
|||||||
expect(formService.getRestFieldValues).toHaveBeenCalledWith(taskId, fieldId);
|
expect(formService.getRestFieldValues).toHaveBeenCalledWith(taskId, fieldId);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle error when requesting fields', () => {
|
it('should handle error when requesting fields with task id', () => {
|
||||||
|
const taskId = '<form-id>';
|
||||||
|
const fieldId = '<field-id>';
|
||||||
|
|
||||||
|
let form = new FormModel({
|
||||||
|
taskId: taskId
|
||||||
|
});
|
||||||
|
|
||||||
|
widget.field = new FormFieldModel(form, {
|
||||||
|
id: fieldId
|
||||||
|
});
|
||||||
const err = 'Error';
|
const err = 'Error';
|
||||||
spyOn(formService, 'getRestFieldValues').and.returnValue(Observable.throw(err));
|
spyOn(formService, 'getRestFieldValues').and.returnValue(Observable.throw(err));
|
||||||
spyOn(widget, 'handleError').and.callThrough();
|
spyOn(widget, 'handleError').and.callThrough();
|
||||||
@ -64,6 +81,27 @@ describe('TypeaheadWidget', () => {
|
|||||||
expect(widget.handleError).toHaveBeenCalledWith(err);
|
expect(widget.handleError).toHaveBeenCalledWith(err);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should handle error when requesting fields with process id', () => {
|
||||||
|
const processDefinitionId = '<process-id>';
|
||||||
|
const fieldId = '<field-id>';
|
||||||
|
|
||||||
|
let form = new FormModel({
|
||||||
|
processDefinitionId: processDefinitionId
|
||||||
|
});
|
||||||
|
|
||||||
|
widget.field = new FormFieldModel(form, {
|
||||||
|
id: fieldId
|
||||||
|
});
|
||||||
|
const err = 'Error';
|
||||||
|
spyOn(formService, 'getRestFieldValuesByProcessId').and.returnValue(Observable.throw(err));
|
||||||
|
spyOn(widget, 'handleError').and.callThrough();
|
||||||
|
|
||||||
|
widget.ngOnInit();
|
||||||
|
|
||||||
|
expect(formService.getRestFieldValuesByProcessId).toHaveBeenCalled();
|
||||||
|
expect(widget.handleError).toHaveBeenCalledWith(err);
|
||||||
|
});
|
||||||
|
|
||||||
it('should log error to console by default', () => {
|
it('should log error to console by default', () => {
|
||||||
spyOn(console, 'error').and.stub();
|
spyOn(console, 'error').and.stub();
|
||||||
widget.handleError('Err');
|
widget.handleError('Err');
|
||||||
@ -143,7 +181,7 @@ describe('TypeaheadWidget', () => {
|
|||||||
id: '1',
|
id: '1',
|
||||||
name: 'name'
|
name: 'name'
|
||||||
};
|
};
|
||||||
|
spyOn(visibilityService, 'refreshVisibility').and.stub();
|
||||||
widget.onItemClick(option, null);
|
widget.onItemClick(option, null);
|
||||||
expect(widget.field.value).toBe(option.id);
|
expect(widget.field.value).toBe(option.id);
|
||||||
expect(widget.value).toBe(option.name);
|
expect(widget.value).toBe(option.name);
|
||||||
@ -157,7 +195,6 @@ describe('TypeaheadWidget', () => {
|
|||||||
]);
|
]);
|
||||||
observer.complete();
|
observer.complete();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
widget.field.value = '2';
|
widget.field.value = '2';
|
||||||
widget.ngOnInit();
|
widget.ngOnInit();
|
||||||
|
|
||||||
@ -337,4 +374,122 @@ describe('TypeaheadWidget', () => {
|
|||||||
done();
|
done();
|
||||||
}, 200);
|
}, 200);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('when template is ready', () => {
|
||||||
|
let typeaheadWidget: TypeaheadWidget;
|
||||||
|
let fixture: ComponentFixture<TypeaheadWidget>;
|
||||||
|
let element: HTMLElement;
|
||||||
|
let componentHandler;
|
||||||
|
let stubFormService;
|
||||||
|
let fakeOptionList: FormFieldOption[] = [{
|
||||||
|
id: '1',
|
||||||
|
name: 'Fake Name 1 '
|
||||||
|
}, {
|
||||||
|
id: '2',
|
||||||
|
name: 'Fake Name 2'
|
||||||
|
}, { id: '3', name: 'Fake Name 3' }];
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
componentHandler = jasmine.createSpyObj('componentHandler', ['upgradeAllRegistered', 'upgradeElement']);
|
||||||
|
window['componentHandler'] = componentHandler;
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
imports: [CoreModule],
|
||||||
|
declarations: [TypeaheadWidget],
|
||||||
|
providers: [FormService, EcmModelService, WidgetVisibilityService]
|
||||||
|
}).compileComponents().then(() => {
|
||||||
|
fixture = TestBed.createComponent(TypeaheadWidget);
|
||||||
|
typeaheadWidget = fixture.componentInstance;
|
||||||
|
element = fixture.nativeElement;
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
fixture.destroy();
|
||||||
|
TestBed.resetTestingModule();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('and typeahead is populated via taskId', () => {
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
stubFormService = fixture.debugElement.injector.get(FormService);
|
||||||
|
visibilityService = fixture.debugElement.injector.get(WidgetVisibilityService);
|
||||||
|
spyOn(visibilityService, 'refreshVisibility').and.stub();
|
||||||
|
spyOn(stubFormService, 'getRestFieldValues').and.returnValue(Observable.of(fakeOptionList));
|
||||||
|
typeaheadWidget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), {
|
||||||
|
id: 'typeahead-id',
|
||||||
|
name: 'typeahead-name',
|
||||||
|
type: FormFieldTypes.TYPEAHEAD,
|
||||||
|
readOnly: false
|
||||||
|
});
|
||||||
|
typeaheadWidget.field.isVisible = true;
|
||||||
|
fixture.detectChanges();
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should show visible typeahead widget', async(() => {
|
||||||
|
expect(element.querySelector('#typeahead-id')).toBeDefined();
|
||||||
|
expect(element.querySelector('#typeahead-id')).not.toBeNull();
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should show typeahead options', async(() => {
|
||||||
|
typeaheadWidget.value = 'F';
|
||||||
|
typeaheadWidget.onKeyUp(null);
|
||||||
|
fixture.detectChanges();
|
||||||
|
fixture.whenStable().then(() => {
|
||||||
|
expect(element.querySelector('#typeahead-id-1')).toBeDefined();
|
||||||
|
expect(element.querySelector('#typeahead-id-1')).not.toBeNull();
|
||||||
|
expect(element.querySelector('#typeahead-id-2')).toBeDefined();
|
||||||
|
expect(element.querySelector('#typeahead-id-2')).not.toBeNull();
|
||||||
|
expect(element.querySelector('#typeahead-id-3')).toBeDefined();
|
||||||
|
expect(element.querySelector('#typeahead-id-3')).not.toBeNull();
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should hide not visibile typeahead', async(() => {
|
||||||
|
typeaheadWidget.field.isVisible = false;
|
||||||
|
fixture.detectChanges();
|
||||||
|
fixture.whenStable().then(() => {
|
||||||
|
expect(element.querySelector('#typeahead-id')).toBeNull();
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('and typeahead is populated via processDefinitionId', () => {
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
stubFormService = fixture.debugElement.injector.get(FormService);
|
||||||
|
visibilityService = fixture.debugElement.injector.get(WidgetVisibilityService);
|
||||||
|
spyOn(visibilityService, 'refreshVisibility').and.stub();
|
||||||
|
spyOn(stubFormService, 'getRestFieldValuesByProcessId').and.returnValue(Observable.of(fakeOptionList));
|
||||||
|
typeaheadWidget.field = new FormFieldModel(new FormModel({ processDefinitionId: 'fake-process-id' }), {
|
||||||
|
id: 'typeahead-id',
|
||||||
|
name: 'typeahead-name',
|
||||||
|
type: FormFieldTypes.TYPEAHEAD,
|
||||||
|
readOnly: 'false'
|
||||||
|
});
|
||||||
|
typeaheadWidget.field.emptyOption = { id: 'empty', name: 'Choose one...' };
|
||||||
|
typeaheadWidget.field.isVisible = true;
|
||||||
|
fixture.detectChanges();
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should show visible typeahead widget', async(() => {
|
||||||
|
expect(element.querySelector('#typeahead-id')).toBeDefined();
|
||||||
|
expect(element.querySelector('#typeahead-id')).not.toBeNull();
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should show typeahead options', async(() => {
|
||||||
|
typeaheadWidget.value = 'F';
|
||||||
|
typeaheadWidget.onKeyUp(null);
|
||||||
|
fixture.detectChanges();
|
||||||
|
fixture.whenStable().then(() => {
|
||||||
|
expect(element.querySelector('#typeahead-id-1')).toBeDefined();
|
||||||
|
expect(element.querySelector('#typeahead-id-1')).not.toBeNull();
|
||||||
|
expect(element.querySelector('#typeahead-id-2')).toBeDefined();
|
||||||
|
expect(element.querySelector('#typeahead-id-2')).not.toBeNull();
|
||||||
|
expect(element.querySelector('#typeahead-id-3')).toBeDefined();
|
||||||
|
expect(element.querySelector('#typeahead-id-3')).not.toBeNull();
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -19,6 +19,7 @@ import { Component, OnInit } from '@angular/core';
|
|||||||
import { FormService } from './../../../services/form.service';
|
import { FormService } from './../../../services/form.service';
|
||||||
import { WidgetComponent } from './../widget.component';
|
import { WidgetComponent } from './../widget.component';
|
||||||
import { FormFieldOption } from './../core/form-field-option';
|
import { FormFieldOption } from './../core/form-field-option';
|
||||||
|
import { WidgetVisibilityService } from '../../../services/widget-visibility.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
moduleId: module.id,
|
moduleId: module.id,
|
||||||
@ -33,15 +34,16 @@ export class TypeaheadWidget extends WidgetComponent implements OnInit {
|
|||||||
value: string;
|
value: string;
|
||||||
options: FormFieldOption[] = [];
|
options: FormFieldOption[] = [];
|
||||||
|
|
||||||
constructor(private formService: FormService) {
|
constructor(private formService: FormService,
|
||||||
|
private visibilityService: WidgetVisibilityService) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
if (this.field.form.processDefinitionId) {
|
if (this.field.form.taskId) {
|
||||||
this.getValuesByProcessDefinitionId();
|
|
||||||
} else {
|
|
||||||
this.getValuesByTaskId();
|
this.getValuesByTaskId();
|
||||||
|
} else {
|
||||||
|
this.getValuesByProcessDefinitionId();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,7 +115,7 @@ export class TypeaheadWidget extends WidgetComponent implements OnInit {
|
|||||||
onBlur() {
|
onBlur() {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.flushValue();
|
this.flushValue();
|
||||||
this.checkVisibility(this.field);
|
this.checkVisibility();
|
||||||
}, 200);
|
}, 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,7 +143,7 @@ export class TypeaheadWidget extends WidgetComponent implements OnInit {
|
|||||||
if (item) {
|
if (item) {
|
||||||
this.field.value = item.id;
|
this.field.value = item.id;
|
||||||
this.value = item.name;
|
this.value = item.name;
|
||||||
this.checkVisibility(this.field);
|
this.checkVisibility();
|
||||||
}
|
}
|
||||||
if (event) {
|
if (event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
@ -152,4 +154,8 @@ export class TypeaheadWidget extends WidgetComponent implements OnInit {
|
|||||||
console.error(error);
|
console.error(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
checkVisibility() {
|
||||||
|
this.visibilityService.refreshVisibility(this.field.form);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user