mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2026-09-09 18:03:21 +00:00
[ADF-1625] removed wrong select into typeahed widget, readded validati… (#2411)
* #ADF-1625 removed wrong select into typeahed widget, readded validation on blur * #ADF-1625 added validator for typeahead fixed tests * #ADF-1625 removed wrong fdescribe * [ADF-1625] cleaned behaviour on typeahed * [ADF-1625] fixed some selection bug on typeahed and start fixing test * [ADF-1625] fixed typeahead test for autocomplete
This commit is contained in:
+54
@@ -18,6 +18,7 @@
|
||||
import { FormFieldOption } from './form-field-option';
|
||||
import { FormFieldTypes } from './form-field-types';
|
||||
import {
|
||||
FixedValueFieldValidator,
|
||||
MaxLengthFieldValidator,
|
||||
MaxValueFieldValidator,
|
||||
MinLengthFieldValidator,
|
||||
@@ -533,4 +534,57 @@ describe('FormFieldValidator', () => {
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('FixedValueFieldValidator', () => {
|
||||
|
||||
let validator: FixedValueFieldValidator;
|
||||
|
||||
beforeEach(() => {
|
||||
validator = new FixedValueFieldValidator();
|
||||
});
|
||||
|
||||
it('should support only typeahead field', () => {
|
||||
let field = new FormFieldModel(new FormModel(), {
|
||||
type: FormFieldTypes.TEXT
|
||||
});
|
||||
expect(validator.isSupported(field)).toBeFalsy();
|
||||
|
||||
field = new FormFieldModel(new FormModel(), {
|
||||
type: FormFieldTypes.TYPEAHEAD
|
||||
});
|
||||
|
||||
expect(validator.isSupported(field)).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should allow empty values', () => {
|
||||
let field = new FormFieldModel(new FormModel(), {
|
||||
type: FormFieldTypes.TYPEAHEAD,
|
||||
value: null,
|
||||
regexPattern: 'pattern'
|
||||
});
|
||||
|
||||
expect(validator.validate(field)).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should succeed for a valid input value in options', () => {
|
||||
let field = new FormFieldModel(new FormModel(), {
|
||||
type: FormFieldTypes.TYPEAHEAD,
|
||||
value: '1',
|
||||
options: [{id: '1', name: 'Leanne Graham'}, {id: '2', name: 'Ervin Howell'}]
|
||||
});
|
||||
|
||||
expect(validator.validate(field)).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should fail for an invalid input value in options', () => {
|
||||
let field = new FormFieldModel(new FormModel(), {
|
||||
type: FormFieldTypes.TYPEAHEAD,
|
||||
value: 'Lean',
|
||||
options: [{id: '1', name: 'Leanne Graham'}, {id: '2', name: 'Ervin Howell'}]
|
||||
});
|
||||
|
||||
expect(validator.validate(field)).toBeFalsy();
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
+43
-1
@@ -366,6 +366,47 @@ export class RegExFieldValidator implements FormFieldValidator {
|
||||
|
||||
}
|
||||
|
||||
export class FixedValueFieldValidator implements FormFieldValidator {
|
||||
|
||||
private supportedTypes = [
|
||||
FormFieldTypes.TYPEAHEAD
|
||||
];
|
||||
|
||||
isSupported(field: FormFieldModel): boolean {
|
||||
return field && this.supportedTypes.indexOf(field.type) > -1;
|
||||
}
|
||||
|
||||
hasValidNameOrValidId(field: FormFieldModel): boolean {
|
||||
return this.hasValidName(field) || this.hasValidId(field);
|
||||
}
|
||||
|
||||
hasValidName(field: FormFieldModel) {
|
||||
return field.options.find(item => item.name && item.name.toLocaleLowerCase() === field.value.toLocaleLowerCase()) ? true : false;
|
||||
}
|
||||
|
||||
hasValidId(field: FormFieldModel) {
|
||||
return field.options[field.value - 1] ? true : false;
|
||||
}
|
||||
|
||||
hasStringValue(field: FormFieldModel) {
|
||||
return field.value && typeof field.value === 'string';
|
||||
}
|
||||
|
||||
hasOptions(field: FormFieldModel) {
|
||||
return field.options && field.options.length > 0;
|
||||
}
|
||||
|
||||
validate(field: FormFieldModel): boolean {
|
||||
if (this.isSupported(field)) {
|
||||
if (this.hasStringValue(field) && this.hasOptions(field) && !this.hasValidNameOrValidId(field)) {
|
||||
field.validationSummary = 'Invalid data inserted';
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
export const FORM_FIELD_VALIDATORS = [
|
||||
new RequiredFieldValidator(),
|
||||
new NumberFieldValidator(),
|
||||
@@ -376,5 +417,6 @@ export const FORM_FIELD_VALIDATORS = [
|
||||
new RegExFieldValidator(),
|
||||
new DateFieldValidator(),
|
||||
new MinDateFieldValidator(),
|
||||
new MaxDateFieldValidator()
|
||||
new MaxDateFieldValidator(),
|
||||
new FixedValueFieldValidator()
|
||||
];
|
||||
|
||||
+3
-5
@@ -10,18 +10,16 @@
|
||||
type="text"
|
||||
[id]="field.id"
|
||||
[(ngModel)]="value"
|
||||
(ngModelChange)="validate()"
|
||||
(keyup)="onKeyUp($event)"
|
||||
[disabled]="field.readOnly"
|
||||
placeholder="{{field.placeholder}}"
|
||||
[mdAutocomplete]="auto">
|
||||
<md-autocomplete #auto="mdAutocomplete" (optionSelected)="onItemSelect($event.option.value)">
|
||||
<md-option *ngFor="let item of options" (click)="onItemClick(item, $event)" [value]="item">
|
||||
<span>{{item.name}}</span>
|
||||
<md-option *ngFor="let item of options" [value]="item">
|
||||
<span [id]="field.name+'_option_'+item.id">{{item.name}}</span>
|
||||
</md-option>
|
||||
</md-autocomplete>
|
||||
<md-select class="adf-select" [id]="field.id" [(ngModel)]="field.value">
|
||||
<md-option id="readonlyOption" *ngIf="isReadOnlyType()" [value]="field.value">{{field.value}}</md-option>
|
||||
</md-select>
|
||||
</md-input-container>
|
||||
|
||||
<error-widget [error]="field.validationSummary"></error-widget>
|
||||
|
||||
+90
-126
@@ -15,6 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { OverlayContainer } from '@angular/cdk/overlay';
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { CoreModule, LogServiceMock } from 'ng2-alfresco-core';
|
||||
import { Observable } from 'rxjs/Rx';
|
||||
@@ -37,6 +38,7 @@ describe('TypeaheadWidgetComponent', () => {
|
||||
let widget: TypeaheadWidgetComponent;
|
||||
let visibilityService: WidgetVisibilityService;
|
||||
let logService: LogServiceMock;
|
||||
let overlayContainerElement: HTMLElement;
|
||||
|
||||
beforeEach(() => {
|
||||
logService = new LogServiceMock();
|
||||
@@ -108,23 +110,6 @@ describe('TypeaheadWidgetComponent', () => {
|
||||
expect(widget.handleError).toHaveBeenCalledWith(err);
|
||||
});
|
||||
|
||||
it('should prevent default behaviour on option item click', () => {
|
||||
let event = jasmine.createSpyObj('event', ['preventDefault']);
|
||||
widget.onItemClick(null, event);
|
||||
expect(event.preventDefault).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should update values on option item click', () => {
|
||||
let option: FormFieldOption = <FormFieldOption> {
|
||||
id: '1',
|
||||
name: 'name'
|
||||
};
|
||||
spyOn(visibilityService, 'refreshVisibility').and.stub();
|
||||
widget.onItemClick(option, null);
|
||||
expect(widget.field.value).toBe(option.id);
|
||||
expect(widget.value).toBe(option.name);
|
||||
});
|
||||
|
||||
it('should setup initial value', () => {
|
||||
spyOn(formService, 'getRestFieldValues').and.returnValue(Observable.create(observer => {
|
||||
observer.next([
|
||||
@@ -208,89 +193,6 @@ describe('TypeaheadWidgetComponent', () => {
|
||||
expect(filtered[0]).toEqual(options[1]);
|
||||
});
|
||||
|
||||
it('should update form on value flush', () => {
|
||||
spyOn(widget.field, 'updateForm').and.callThrough();
|
||||
widget.flushValue();
|
||||
expect(widget.field.updateForm).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should flush selected value', () => {
|
||||
let options: FormFieldOption[] = [
|
||||
{ id: '1', name: 'Item one' },
|
||||
{ id: '2', name: 'Item Two' }
|
||||
];
|
||||
|
||||
widget.field.options = options;
|
||||
widget.value = 'Item Two';
|
||||
widget.flushValue();
|
||||
|
||||
expect(widget.value).toBe(options[1].name);
|
||||
expect(widget.field.value).toBe(options[1].id);
|
||||
});
|
||||
|
||||
it('should be case insensitive when flushing value', () => {
|
||||
let options: FormFieldOption[] = [
|
||||
{ id: '1', name: 'Item one' },
|
||||
{ id: '2', name: 'iTEM TWo' }
|
||||
];
|
||||
|
||||
widget.field.options = options;
|
||||
widget.value = 'ITEM TWO';
|
||||
widget.flushValue();
|
||||
|
||||
expect(widget.value).toBe(options[1].name);
|
||||
expect(widget.field.value).toBe(options[1].id);
|
||||
});
|
||||
|
||||
it('should reset fields when flushing missing option value', () => {
|
||||
widget.field.options = [
|
||||
{ id: '1', name: 'Item one' },
|
||||
{ id: '2', name: 'Item two' }
|
||||
];
|
||||
widget.value = 'Missing item';
|
||||
widget.flushValue();
|
||||
|
||||
expect(widget.value).toBeNull();
|
||||
expect(widget.field.value).toBeNull();
|
||||
});
|
||||
|
||||
it('should reset fields when flushing incorrect value', () => {
|
||||
widget.field.options = [
|
||||
{ id: '1', name: 'Item one' },
|
||||
{ id: '2', name: 'Item two' }
|
||||
];
|
||||
widget.field.value = 'Item two';
|
||||
widget.value = 'Item two!';
|
||||
widget.flushValue();
|
||||
|
||||
expect(widget.value).toBeNull();
|
||||
expect(widget.field.value).toBeNull();
|
||||
});
|
||||
|
||||
it('should reset fields when flushing value having no options', () => {
|
||||
widget.field.options = null;
|
||||
widget.field.value = 'item 1';
|
||||
widget.value = 'new item';
|
||||
widget.flushValue();
|
||||
|
||||
expect(widget.value).toBeNull();
|
||||
expect(widget.field.value).toBeNull();
|
||||
});
|
||||
|
||||
it('should emit field change event on item click', () => {
|
||||
let event = jasmine.createSpyObj('event', ['preventDefault']);
|
||||
let fakeField = new FormFieldModel(new FormModel(), { id: 'fakeField', value: 'fakeValue' });
|
||||
widget.field = fakeField;
|
||||
let item = { id: 'fake-id-opt', name: 'fake-name-opt' };
|
||||
widget.onItemClick(item, event);
|
||||
|
||||
widget.fieldChanged.subscribe((field) => {
|
||||
expect(field).toBeDefined();
|
||||
expect(field.id).toEqual('fakeField');
|
||||
expect(field.value).toEqual('fake-id-opt');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when template is ready', () => {
|
||||
let typeaheadWidgetComponent: TypeaheadWidgetComponent;
|
||||
let fixture: ComponentFixture<TypeaheadWidgetComponent>;
|
||||
@@ -308,7 +210,19 @@ describe('TypeaheadWidgetComponent', () => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [CoreModule, MaterialModule],
|
||||
declarations: [TypeaheadWidgetComponent, ErrorWidgetComponent],
|
||||
providers: [FormService, EcmModelService, WidgetVisibilityService]
|
||||
providers: [
|
||||
{provide: OverlayContainer, useFactory: () => {
|
||||
overlayContainerElement = document.createElement('div');
|
||||
overlayContainerElement.classList.add('cdk-overlay-container');
|
||||
|
||||
document.body.appendChild(overlayContainerElement);
|
||||
|
||||
// remove body padding to keep consistent cross-browser
|
||||
document.body.style.padding = '0';
|
||||
document.body.style.margin = '0';
|
||||
|
||||
return {getContainerElement: () => overlayContainerElement};
|
||||
}}, FormService, EcmModelService, WidgetVisibilityService]
|
||||
}).compileComponents().then(() => {
|
||||
fixture = TestBed.createComponent(TypeaheadWidgetComponent);
|
||||
typeaheadWidgetComponent = fixture.componentInstance;
|
||||
@@ -321,6 +235,33 @@ describe('TypeaheadWidgetComponent', () => {
|
||||
TestBed.resetTestingModule();
|
||||
});
|
||||
|
||||
describe ('and typeahead is in readonly mode', () => {
|
||||
|
||||
it('should show typeahead value with input disabled', async(() => {
|
||||
typeaheadWidgetComponent.field = new FormFieldModel(
|
||||
new FormModel({ processVariables: [{ name: 'typeahead-id_LABEL', value: 'FakeProcessValue' }] }), {
|
||||
id: 'typeahead-id',
|
||||
name: 'typeahead-name',
|
||||
type: 'readonly',
|
||||
params: { field: { id: 'typeahead-id', name: 'typeahead-name', type: 'typeahead' } }
|
||||
});
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable().then(() => {
|
||||
fixture.detectChanges();
|
||||
let readonlyInput: HTMLInputElement = <HTMLInputElement> element.querySelector('#typeahead-id');
|
||||
expect(readonlyInput.disabled).toBeTruthy();
|
||||
expect(readonlyInput).not.toBeNull();
|
||||
expect(readonlyInput.value).toBe('FakeProcessValue');
|
||||
});
|
||||
}));
|
||||
|
||||
afterEach(() => {
|
||||
fixture.destroy();
|
||||
TestBed.resetTestingModule();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('and typeahead is populated via taskId', () => {
|
||||
|
||||
beforeEach(async(() => {
|
||||
@@ -344,14 +285,58 @@ describe('TypeaheadWidgetComponent', () => {
|
||||
}));
|
||||
|
||||
it('should show typeahead options', async(() => {
|
||||
let keyboardEvent = new KeyboardEvent('keypress');
|
||||
let typeahedElement = fixture.debugElement.query(By.css('#typeahead-id'));
|
||||
let typeahedHTMLElement: HTMLInputElement = <HTMLInputElement> typeahedElement.nativeElement;
|
||||
typeahedHTMLElement.focus();
|
||||
typeaheadWidgetComponent.value = 'F';
|
||||
typeahedHTMLElement.value = 'F';
|
||||
typeahedHTMLElement.dispatchEvent(new Event('keyup'));
|
||||
typeahedHTMLElement.dispatchEvent(new Event('input'));
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable().then(() => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.query(By.css('[id="typeahead-name_option_1"]'))).not.toBeNull();
|
||||
expect(fixture.debugElement.query(By.css('[id="typeahead-name_option_2"]'))).not.toBeNull();
|
||||
expect(fixture.debugElement.query(By.css('[id="typeahead-name_option_3"]'))).not.toBeNull();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should hide the option when the value is empty', async(() => {
|
||||
let typeahedElement = fixture.debugElement.query(By.css('#typeahead-id'));
|
||||
let typeahedHTMLElement: HTMLInputElement = <HTMLInputElement> typeahedElement.nativeElement;
|
||||
typeahedHTMLElement.focus();
|
||||
typeaheadWidgetComponent.value = 'F';
|
||||
typeahedHTMLElement.value = 'F';
|
||||
typeahedHTMLElement.dispatchEvent(new Event('keyup'));
|
||||
typeahedHTMLElement.dispatchEvent(new Event('input'));
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable().then(() => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.query(By.css('[id="typeahead-name_option_1"]'))).not.toBeNull();
|
||||
typeahedHTMLElement.focus();
|
||||
typeaheadWidgetComponent.value = '';
|
||||
typeahedHTMLElement.dispatchEvent(new Event('keyup'));
|
||||
typeahedHTMLElement.dispatchEvent(new Event('input'));
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable().then(() => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.query(By.css('[id="typeahead-name_option_1"]'))).toBeNull();
|
||||
});
|
||||
});
|
||||
}));
|
||||
|
||||
it('should show error message when the value is not valid', async(() => {
|
||||
typeaheadWidgetComponent.value = 'Fake Name';
|
||||
typeaheadWidgetComponent.field.value = 'Fake Name';
|
||||
typeaheadWidgetComponent.field.options = fakeOptionList;
|
||||
expect(element.querySelector('.adf-error-text')).toBeNull();
|
||||
let keyboardEvent = new KeyboardEvent('keypress');
|
||||
typeaheadWidgetComponent.onKeyUp(keyboardEvent);
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable().then(() => {
|
||||
expect(fixture.debugElement.queryAll(By.css('[id="md-option-1"]'))).toBeDefined();
|
||||
expect(fixture.debugElement.queryAll(By.css('[id="md-option-2"]'))).toBeDefined();
|
||||
expect(fixture.debugElement.queryAll(By.css('[id="md-option-3"]'))).toBeDefined();
|
||||
fixture.detectChanges();
|
||||
expect(element.querySelector('.adf-error-text')).not.toBeNull();
|
||||
expect(element.querySelector('.adf-error-text').textContent).toContain('Invalid data inserted');
|
||||
});
|
||||
}));
|
||||
|
||||
@@ -362,27 +347,6 @@ describe('TypeaheadWidgetComponent', () => {
|
||||
expect(element.querySelector('#typeahead-id')).toBeNull();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should show typeahead value when the type is readonly', async(() => {
|
||||
typeaheadWidgetComponent.field = new FormFieldModel(
|
||||
new FormModel({ taskId: 'fake-task-id', processVariables: [{ name: 'typeahead-id_LABEL', value: 'FakeProcessValue' }] }), {
|
||||
id: 'typeahead-id',
|
||||
name: 'typeahead-name',
|
||||
type: 'readonly',
|
||||
value: '9',
|
||||
params: { field: { id: 'typeahead-id', name: 'typeahead-name', type: 'typeahead' } }
|
||||
});
|
||||
fixture.detectChanges();
|
||||
const trigger = fixture.debugElement.query(By.css('.mat-select-trigger')).nativeElement;
|
||||
trigger.click();
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable().then(() => {
|
||||
expect(element.querySelector('#typeahead-id')).not.toBeNull();
|
||||
let optionElement: HTMLElement = <HTMLElement> document.body.querySelector('.mat-option');
|
||||
expect(optionElement.innerText).toEqual('FakeProcessValue');
|
||||
});
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
describe('and typeahead is populated via processDefinitionId', () => {
|
||||
|
||||
+57
-61
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/* tslint:disable:component-selector */
|
||||
/* tslint:disable:component-selector */
|
||||
|
||||
import { ENTER, ESCAPE } from '@angular/cdk/keycodes';
|
||||
import { Component, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
@@ -23,7 +23,7 @@ import { LogService } from 'ng2-alfresco-core';
|
||||
import { WidgetVisibilityService } from '../../../services/widget-visibility.service';
|
||||
import { FormService } from './../../../services/form.service';
|
||||
import { FormFieldOption } from './../core/form-field-option';
|
||||
import { baseHost , WidgetComponent } from './../widget.component';
|
||||
import { baseHost, WidgetComponent } from './../widget.component';
|
||||
|
||||
@Component({
|
||||
selector: 'typeahead-widget',
|
||||
@@ -42,7 +42,7 @@ export class TypeaheadWidgetComponent extends WidgetComponent implements OnInit
|
||||
constructor(public formService: FormService,
|
||||
private visibilityService: WidgetVisibilityService,
|
||||
private logService: LogService) {
|
||||
super(formService);
|
||||
super(formService);
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
@@ -51,101 +51,89 @@ export class TypeaheadWidgetComponent extends WidgetComponent implements OnInit
|
||||
} else if (this.field.form.processDefinitionId) {
|
||||
this.getValuesByProcessDefinitionId();
|
||||
}
|
||||
if (this.isReadOnlyType()) {
|
||||
this.value = this.field.value;
|
||||
}
|
||||
}
|
||||
|
||||
getValuesByTaskId() {
|
||||
this.formService
|
||||
.getRestFieldValues(
|
||||
this.field.form.taskId,
|
||||
this.field.id
|
||||
this.field.form.taskId,
|
||||
this.field.id
|
||||
)
|
||||
.subscribe(
|
||||
(result: FormFieldOption[]) => {
|
||||
let options = result || [];
|
||||
this.field.options = options;
|
||||
(result: FormFieldOption[]) => {
|
||||
let options = result || [];
|
||||
this.field.options = options;
|
||||
|
||||
let fieldValue = this.field.value;
|
||||
if (fieldValue) {
|
||||
let toSelect = options.find(item => item.id === fieldValue);
|
||||
if (toSelect) {
|
||||
this.value = toSelect.name;
|
||||
}
|
||||
let fieldValue = this.field.value;
|
||||
if (fieldValue) {
|
||||
let toSelect = options.find(item => item.id === fieldValue);
|
||||
if (toSelect) {
|
||||
this.value = toSelect.name;
|
||||
}
|
||||
this.field.updateForm();
|
||||
this.visibilityService.refreshEntityVisibility(this.field);
|
||||
},
|
||||
err => this.handleError(err)
|
||||
}
|
||||
this.field.updateForm();
|
||||
this.visibilityService.refreshEntityVisibility(this.field);
|
||||
},
|
||||
err => this.handleError(err)
|
||||
);
|
||||
}
|
||||
|
||||
getValuesByProcessDefinitionId() {
|
||||
this.formService
|
||||
.getRestFieldValuesByProcessId(
|
||||
this.field.form.processDefinitionId,
|
||||
this.field.id
|
||||
this.field.form.processDefinitionId,
|
||||
this.field.id
|
||||
)
|
||||
.subscribe(
|
||||
(result: FormFieldOption[]) => {
|
||||
let options = result || [];
|
||||
this.field.options = options;
|
||||
(result: FormFieldOption[]) => {
|
||||
let options = result || [];
|
||||
this.field.options = options;
|
||||
|
||||
let fieldValue = this.field.value;
|
||||
if (fieldValue) {
|
||||
let toSelect = options.find(item => item.id === fieldValue);
|
||||
if (toSelect) {
|
||||
this.value = toSelect.name;
|
||||
}
|
||||
let fieldValue = this.field.value;
|
||||
if (fieldValue) {
|
||||
let toSelect = options.find(item => item.id === fieldValue);
|
||||
if (toSelect) {
|
||||
this.value = toSelect.name;
|
||||
}
|
||||
this.field.updateForm();
|
||||
this.visibilityService.refreshEntityVisibility(this.field);
|
||||
},
|
||||
err => this.handleError(err)
|
||||
}
|
||||
this.field.updateForm();
|
||||
this.visibilityService.refreshEntityVisibility(this.field);
|
||||
},
|
||||
err => this.handleError(err)
|
||||
);
|
||||
}
|
||||
|
||||
getOptions(): FormFieldOption[] {
|
||||
let val = this.value.toLocaleLowerCase();
|
||||
let val = this.value.trim().toLocaleLowerCase();
|
||||
return this.field.options.filter(item => {
|
||||
let name = item.name.toLocaleLowerCase();
|
||||
return name.indexOf(val) > -1;
|
||||
});
|
||||
}
|
||||
|
||||
isValidOptionName(optionName: string): boolean {
|
||||
let option = this.field.options.find(item => item.name && item.name.toLocaleLowerCase() === optionName.toLocaleLowerCase());
|
||||
return option ? true : false;
|
||||
}
|
||||
|
||||
onKeyUp(event: KeyboardEvent) {
|
||||
if (this.value && this.value.length >= this.minTermLength && this.oldValue !== this.value) {
|
||||
if (this.value && this.value.trim().length >= this.minTermLength && this.oldValue !== this.value) {
|
||||
if (event.keyCode !== ESCAPE && event.keyCode !== ENTER) {
|
||||
if (this.value.length >= this.minTermLength) {
|
||||
this.options = this.getOptions();
|
||||
this.oldValue = this.value;
|
||||
if (this.isValidOptionName(this.value)) {
|
||||
this.field.value = this.options[0].id;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
flushValue() {
|
||||
let options = this.field.options || [];
|
||||
let lValue = this.value ? this.value.toLocaleLowerCase() : null;
|
||||
|
||||
let field = options.find(item => item.name && item.name.toLocaleLowerCase() === lValue);
|
||||
if (field) {
|
||||
this.field.value = field.id;
|
||||
this.value = field.name;
|
||||
} else {
|
||||
this.field.value = null;
|
||||
this.value = null;
|
||||
}
|
||||
|
||||
this.field.updateForm();
|
||||
}
|
||||
|
||||
onItemClick(item: FormFieldOption, event: Event) {
|
||||
if (item) {
|
||||
this.field.value = item.id;
|
||||
this.value = item.name;
|
||||
this.checkVisibility();
|
||||
}
|
||||
if (event) {
|
||||
event.preventDefault();
|
||||
if (this.isValueDefined() && this.value.trim().length === 0) {
|
||||
this.oldValue = this.value;
|
||||
this.options = [];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,6 +145,14 @@ export class TypeaheadWidgetComponent extends WidgetComponent implements OnInit
|
||||
}
|
||||
}
|
||||
|
||||
validate() {
|
||||
this.field.value = this.value;
|
||||
}
|
||||
|
||||
isValueDefined() {
|
||||
return this.value !== null && this.value !== undefined;
|
||||
}
|
||||
|
||||
handleError(error: any) {
|
||||
this.logService.error(error);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user