diff --git a/lib/core/form/components/form-field/form-field.component.spec.ts b/lib/core/form/components/form-field/form-field.component.spec.ts index 07fe29ddf2..866a04db0c 100644 --- a/lib/core/form/components/form-field/form-field.component.spec.ts +++ b/lib/core/form/components/form-field/form-field.component.spec.ts @@ -20,11 +20,13 @@ import { MaterialModule } from '../../../material.module'; import { ErrorWidgetComponent } from '../widgets/error/error.component'; import { FormRenderingService } from './../../services/form-rendering.service'; import { WidgetVisibilityService } from './../../services/widget-visibility.service'; -import { CheckboxWidgetComponent } from './../widgets/checkbox/checkbox.widget'; import { FormFieldModel, FormFieldTypes, FormModel } from './../widgets/core/index'; import { InputMaskDirective } from './../widgets/text/text-mask.component'; -import { TextWidgetComponent } from './../widgets/text/text.widget'; +import { TextWidgetComponent, CheckboxWidgetComponent, WidgetComponent } from '../widgets/index'; import { FormFieldComponent } from './form-field.component'; +import { BrowserDynamicTestingModule } from '@angular/platform-browser-dynamic/testing'; +import { FormService } from '../../services/form.service'; +import { EcmModelService } from '../../services/ecm-model.service'; describe('FormFieldComponent', () => { @@ -35,22 +37,33 @@ describe('FormFieldComponent', () => { let formRenderingService: FormRenderingService; beforeEach(async(() => { + TestBed.configureTestingModule({ - imports: [ - MaterialModule - ], - declarations: [ - FormFieldComponent, - TextWidgetComponent, - CheckboxWidgetComponent, - InputMaskDirective, - ErrorWidgetComponent], - providers: [ - FormRenderingService, - WidgetVisibilityService - ] - }) - .compileComponents(); + imports: [ + MaterialModule + ], + declarations: [ + FormFieldComponent, + WidgetComponent, + TextWidgetComponent, + CheckboxWidgetComponent, + InputMaskDirective, + ErrorWidgetComponent], + providers: [ + FormRenderingService, + WidgetVisibilityService, + FormService, + EcmModelService + ] + }); + + TestBed.overrideModule(BrowserDynamicTestingModule, { + set: { + entryComponents: [WidgetComponent, TextWidgetComponent, CheckboxWidgetComponent] + } + }); + + TestBed.compileComponents(); })); beforeEach(() => { @@ -60,9 +73,14 @@ describe('FormFieldComponent', () => { form = new FormModel(); }); - xit('should create default component instance', () => { + afterEach(() => { + fixture.destroy(); + }); + + it('should create default component instance', () => { let field = new FormFieldModel(form, { - type: FormFieldTypes.TEXT + type: FormFieldTypes.TEXT, + id: 'FAKE-TXT-WIDGET' }); component.field = field; @@ -72,9 +90,10 @@ describe('FormFieldComponent', () => { expect(component.componentRef.componentType).toBe(TextWidgetComponent); }); - xit('should create custom component instance', () => { + it('should create custom component instance', () => { let field = new FormFieldModel(form, { - type: FormFieldTypes.TEXT + type: FormFieldTypes.TEXT, + id: 'FAKE-TXT-WIDGET' }); formRenderingService.setComponentTypeResolver(FormFieldTypes.TEXT, () => CheckboxWidgetComponent, true); @@ -87,7 +106,8 @@ describe('FormFieldComponent', () => { it('should require component type to be resolved', () => { let field = new FormFieldModel(form, { - type: FormFieldTypes.TEXT + type: FormFieldTypes.TEXT, + id: 'FAKE-TXT-WIDGET' }); spyOn(formRenderingService, 'resolveComponentType').and.returnValue(null); @@ -98,4 +118,41 @@ describe('FormFieldComponent', () => { expect(component.componentRef).toBeUndefined(); }); + it('should hide the field when it is not visible', () => { + let field = new FormFieldModel(form, { + type: FormFieldTypes.TEXT, + id: 'FAKE-TXT-WIDGET' + }); + + component.field = field; + component.field.isVisible = false; + fixture.detectChanges(); + expect(fixture.nativeElement.querySelector('#field-FAKE-TXT-WIDGET-container').hidden).toBeTruthy(); + }); + + it('should show the field when it is visible', () => { + let field = new FormFieldModel(form, { + type: FormFieldTypes.TEXT, + id: 'FAKE-TXT-WIDGET' + }); + + component.field = field; + fixture.detectChanges(); + expect(fixture.nativeElement.querySelector('#field-FAKE-TXT-WIDGET-container').hidden).toBeFalsy(); + }); + + it('should hide a visible element', () => { + let field = new FormFieldModel(form, { + type: FormFieldTypes.TEXT, + id: 'FAKE-TXT-WIDGET' + }); + + component.field = field; + fixture.detectChanges(); + expect(fixture.nativeElement.querySelector('#field-FAKE-TXT-WIDGET-container').hidden).toBeFalsy(); + component.field.isVisible = false; + fixture.detectChanges(); + expect(fixture.nativeElement.querySelector('#field-FAKE-TXT-WIDGET-container').hidden).toBeTruthy(); + }); + }); diff --git a/lib/core/form/components/form-field/form-field.component.ts b/lib/core/form/components/form-field/form-field.component.ts index c47ce49d06..a87fbf3ae7 100644 --- a/lib/core/form/components/form-field/form-field.component.ts +++ b/lib/core/form/components/form-field/form-field.component.ts @@ -40,7 +40,8 @@ declare var adf: any; @Component({ selector: 'adf-form-field, form-field', template: ` -
@@ -96,7 +97,8 @@ export class FormFieldComponent implements OnInit, OnDestroy { instance.field = this.field; instance.fieldChanged.subscribe(field => { if (field && this.field.form) { - this.visibilityService.refreshVisibility(this.field.form); + this.visibilityService.refreshVisibility(field.form); + field.form.onFormFieldChanged(field); } }); } diff --git a/lib/core/form/components/form.component.html b/lib/core/form/components/form.component.html index 47972a0448..87e59c9be2 100644 --- a/lib/core/form/components/form.component.html +++ b/lib/core/form/components/form.component.html @@ -19,7 +19,7 @@
- +
diff --git a/lib/core/form/components/form.component.visibility.spec.ts b/lib/core/form/components/form.component.visibility.spec.ts index 8a5835c991..304a4dca3b 100644 --- a/lib/core/form/components/form.component.visibility.spec.ts +++ b/lib/core/form/components/form.component.visibility.spec.ts @@ -62,6 +62,10 @@ describe('FormComponent UI and visibiltiy', () => { service = fixture.debugElement.injector.get(FormService); }); + afterEach(() => { + fixture.destroy(); + }); + it('should create instance of FormComponent', () => { expect(fixture.componentInstance instanceof FormComponent).toBe(true, 'should create FormComponent'); }); @@ -124,12 +128,13 @@ describe('FormComponent UI and visibiltiy', () => { component.ngOnChanges({ 'taskId': change }); fixture.detectChanges(); - let firstEl = fixture.debugElement.query(By.css('#country')); - expect(firstEl).toBeNull(); + let firstEl = fixture.debugElement.query(By.css('#field-country-container')); + expect(firstEl.nativeElement.hidden).toBeTruthy(); let secondEl = fixture.debugElement.query(By.css('#name')); expect(secondEl).not.toBeNull(); expect(secondEl).toBeDefined(); + expect(fixture.nativeElement.querySelector('#field-name-container').hidden).toBeFalsy(); }); it('should hide the field based on the previous one', () => { @@ -143,9 +148,10 @@ describe('FormComponent UI and visibiltiy', () => { let firstEl = fixture.debugElement.query(By.css('#name')); expect(firstEl).not.toBeNull(); expect(firstEl).toBeDefined(); + expect(fixture.nativeElement.querySelector('#field-name-container').hidden).toBeFalsy(); - let secondEl = fixture.debugElement.query(By.css('#country')); - expect(secondEl).toBeNull(); + let secondEl = fixture.debugElement.query(By.css('#field-country-container')); + expect(secondEl.nativeElement.hidden).toBeTruthy(); }); it('should show the hidden field when the visibility condition change to true', () => { @@ -156,20 +162,19 @@ describe('FormComponent UI and visibiltiy', () => { component.ngOnChanges({ 'taskId': change }); fixture.detectChanges(); - let firstEl = fixture.debugElement.query(By.css('#country')); - expect(firstEl).toBeNull(); + let firstEl = fixture.debugElement.query(By.css('#field-country-container')); + expect(firstEl.nativeElement.hidden).toBeTruthy(); - const secondEl = fixture.debugElement.query(By.css('#name')); - expect(secondEl).not.toBeNull(); + const secondEl = fixture.debugElement.query(By.css('#field-name-container')); + expect(secondEl.nativeElement.hidden).toBeFalsy(); - let el = secondEl.nativeElement; - - el.value = 'italy'; - el.dispatchEvent(new Event('input')); + let inputElement = fixture.nativeElement.querySelector('#name'); + inputElement.value = 'italy'; + inputElement.dispatchEvent(new Event('input')); fixture.detectChanges(); - firstEl = fixture.debugElement.query(By.css('#country')); - expect(firstEl).not.toBeNull(); + firstEl = fixture.debugElement.query(By.css('#field-country-container')); + expect(firstEl.nativeElement.hidden).toBeFalsy(); }); }); diff --git a/lib/core/form/components/widgets/amount/amount.widget.html b/lib/core/form/components/widgets/amount/amount.widget.html index a03c1470a6..e70e41eb77 100644 --- a/lib/core/form/components/widgets/amount/amount.widget.html +++ b/lib/core/form/components/widgets/amount/amount.widget.html @@ -9,7 +9,7 @@ [required]="isRequired()" [value]="field.value" [(ngModel)]="field.value" - (ngModelChange)="checkVisibility(field)" + (ngModelChange)="onFieldChanged(field)" [disabled]="field.readOnly" placeholder="{{field.placeholder}}"> diff --git a/lib/core/form/components/widgets/checkbox/checkbox.widget.html b/lib/core/form/components/widgets/checkbox/checkbox.widget.html index f0b0293801..f5c7c23640 100644 --- a/lib/core/form/components/widgets/checkbox/checkbox.widget.html +++ b/lib/core/form/components/widgets/checkbox/checkbox.widget.html @@ -5,7 +5,7 @@ [required]="field.required" [disabled]="field.readOnly || readOnly" [(ngModel)]="field.value" - (change)="onChange()"> + (ngModelChange)="onFieldChanged(field)"> {{field.name}} * diff --git a/lib/core/form/components/widgets/checkbox/checkbox.widget.ts b/lib/core/form/components/widgets/checkbox/checkbox.widget.ts index a4ccf77b95..6b8471463c 100644 --- a/lib/core/form/components/widgets/checkbox/checkbox.widget.ts +++ b/lib/core/form/components/widgets/checkbox/checkbox.widget.ts @@ -18,7 +18,6 @@ /* tslint:disable:component-selector no-input-rename */ import { Component, ViewEncapsulation } from '@angular/core'; -import { WidgetVisibilityService } from '../../../services/widget-visibility.service'; import { FormService } from './../../../services/form.service'; import { baseHost , WidgetComponent } from './../widget.component'; @@ -30,12 +29,8 @@ import { baseHost , WidgetComponent } from './../widget.component'; }) export class CheckboxWidgetComponent extends WidgetComponent { - constructor(private visibilityService: WidgetVisibilityService, public formService: FormService) { + constructor(public formService: FormService) { super(formService); } - onChange() { - this.visibilityService.refreshVisibility(this.field.form); - } - } diff --git a/lib/core/form/components/widgets/container/container.widget.html b/lib/core/form/components/widgets/container/container.widget.html index fc9a3e5abb..4aee462184 100644 --- a/lib/core/form/components/widgets/container/container.widget.html +++ b/lib/core/form/components/widgets/container/container.widget.html @@ -1,17 +1,17 @@ -
+

{{content.name}}

-
+
diff --git a/lib/core/form/components/widgets/container/container.widget.spec.ts b/lib/core/form/components/widgets/container/container.widget.spec.ts index cfb7bc115d..5d7c3e23f4 100644 --- a/lib/core/form/components/widgets/container/container.widget.spec.ts +++ b/lib/core/form/components/widgets/container/container.widget.spec.ts @@ -17,7 +17,7 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { ActivitiContentService } from '../../../services/activiti-alfresco.service'; -import { fakeFormJson } from '../../../../mock'; + import { MaterialModule } from '../../../../material.module'; import { WIDGET_DIRECTIVES } from '../index'; import { MASK_DIRECTIVE } from '../index'; @@ -36,7 +36,6 @@ describe('ContainerWidgetComponent', () => { let widget: ContainerWidgetComponent; let fixture: ComponentFixture; - let element: HTMLElement; beforeEach(async(() => { TestBed.configureTestingModule({ @@ -54,11 +53,13 @@ describe('ContainerWidgetComponent', () => { beforeEach(() => { fixture = TestBed.createComponent(ContainerWidgetComponent); - - element = fixture.nativeElement; widget = fixture.componentInstance; }); + afterEach(() => { + fixture.destroy(); + }); + it('should wrap field with model instance', () => { let field = new FormFieldModel(null); widget.field = field; @@ -125,83 +126,6 @@ describe('ContainerWidgetComponent', () => { widget.onFieldChanged(fakeField); }); - describe('when template is ready', () => { - let fakeContainerVisible; - let fakeContainerInvisible; - - beforeEach(() => { - fakeContainerVisible = new ContainerWidgetComponentModel(new FormFieldModel(new FormModel(fakeFormJson), { - fieldType: FormFieldTypes.GROUP, - id: 'fake-cont-id-1', - name: 'fake-cont-1-name', - type: FormFieldTypes.GROUP - })); - fakeContainerInvisible = new ContainerWidgetComponentModel(new FormFieldModel(new FormModel(fakeFormJson), { - fieldType: FormFieldTypes.GROUP, - id: 'fake-cont-id-2', - name: 'fake-cont-2-name', - type: FormFieldTypes.GROUP - })); - fakeContainerVisible.field.isVisible = true; - fakeContainerInvisible.field.isVisible = false; - }); - - afterEach(() => { - fixture.destroy(); - TestBed.resetTestingModule(); - }); - - it('should show the container header when it is visible', () => { - widget.content = fakeContainerVisible; - fixture.detectChanges(); - fixture.whenStable() - .then(() => { - expect(element.querySelector('.container-widget__header').classList.contains('hidden')).toBe(false); - expect(element.querySelector('#container-header-label')).toBeDefined(); - expect(element.querySelector('#container-header-label').innerHTML).toContain('fake-cont-1-name'); - }); - }); - - it('should not show the container header when it is not visible', () => { - widget.content = fakeContainerInvisible; - fixture.detectChanges(); - fixture.whenStable() - .then(() => { - expect(element.querySelector('.container-widget__header').getAttribute('hidden')).not.toBeNull(); - }); - }); - - it('should hide header when it becomes not visible', async(() => { - widget.content = fakeContainerVisible; - fixture.detectChanges(); - widget.fieldChanged.subscribe((res) => { - widget.content.field.isVisible = false; - fixture.detectChanges(); - fixture.whenStable() - .then(() => { - expect(element.querySelector('.container-widget__header').getAttribute('hidden')).not.toBeNull(); - }); - }); - widget.onFieldChanged(null); - })); - - it('should show header when it becomes visible', async(() => { - widget.content = fakeContainerInvisible; - widget.fieldChanged.subscribe((res) => { - widget.content.field.isVisible = true; - fixture.detectChanges(); - fixture.whenStable() - .then(() => { - expect(element.querySelector('#container-header')).toBeDefined(); - expect(element.querySelector('#container-header')).not.toBeNull(); - expect(element.querySelector('#container-header-label')).toBeDefined(); - expect(element.querySelector('#container-header-label').innerHTML).toContain('fake-cont-2-name'); - }); - }); - widget.onFieldChanged(null); - })); - }); - describe('fields', () => { it('should serializes the content fields', () => { diff --git a/lib/core/form/components/widgets/core/form-field.model.ts b/lib/core/form/components/widgets/core/form-field.model.ts index 5e13e96842..4e4fd6a816 100644 --- a/lib/core/form/components/widgets/core/form-field.model.ts +++ b/lib/core/form/components/widgets/core/form-field.model.ts @@ -85,7 +85,6 @@ export class FormFieldModel extends FormWidgetModel { set value(v: any) { this._value = v; - this.validate(); this.updateForm(); } diff --git a/lib/core/form/components/widgets/date-time/date-time.widget.html b/lib/core/form/components/widgets/date-time/date-time.widget.html index b0fa611d39..6f85bb9338 100644 --- a/lib/core/form/components/widgets/date-time/date-time.widget.html +++ b/lib/core/form/components/widgets/date-time/date-time.widget.html @@ -1,4 +1,4 @@ -
diff --git a/lib/core/form/components/widgets/date-time/date-time.widget.spec.ts b/lib/core/form/components/widgets/date-time/date-time.widget.spec.ts index b68995f8b6..d90fcc67e6 100644 --- a/lib/core/form/components/widgets/date-time/date-time.widget.spec.ts +++ b/lib/core/form/components/widgets/date-time/date-time.widget.spec.ts @@ -102,7 +102,7 @@ describe('DateTimeWidgetComponent', () => { }); it('should eval visibility on date changed', () => { - spyOn(widget, 'checkVisibility').and.callThrough(); + spyOn(widget, 'onFieldChanged').and.callThrough(); let field = new FormFieldModel(new FormModel(), { id: 'date-field-id', @@ -115,7 +115,7 @@ describe('DateTimeWidgetComponent', () => { widget.field = field; widget.onDateChanged({ value: moment('13-03-1982 10:00 AM') }); - expect(widget.checkVisibility).toHaveBeenCalledWith(field); + expect(widget.onFieldChanged).toHaveBeenCalledWith(field); }); describe('template check', () => { @@ -173,6 +173,7 @@ describe('DateTimeWidgetComponent', () => { fixture.detectChanges(); fixture.whenStable() .then(() => { + fixture.detectChanges(); expect(element.querySelector('#date-field-id')).toBeDefined(); expect(element.querySelector('#date-field-id')).not.toBeNull(); let dateElement: any = element.querySelector('#date-field-id'); @@ -180,74 +181,6 @@ describe('DateTimeWidgetComponent', () => { }); })); - it('should hide not visible date widget', async(() => { - widget.field = new FormFieldModel(new FormModel(), { - id: 'date-field-id', - name: 'date-name', - value: '12-30-9999 10:30 AM', - dateDisplayFormat: 'MM-DD-YYYY HH:mm A', - type: 'datetime', - readOnly: 'false' - }); - fixture.detectChanges(); - expect(element.querySelector('#data-time-widget')).not.toBeNull(); - widget.field.isVisible = false; - fixture.detectChanges(); - fixture.whenStable() - .then(() => { - fixture.detectChanges(); - expect(element.querySelector('#data-time-widget')).toBeNull(); - }); - })); - - it('should become visibile if the visibility change to true', async(() => { - widget.field = new FormFieldModel(new FormModel(), { - id: 'date-field-id', - name: 'date-name', - value: '12-30-9999 10:30 AM', - dateDisplayFormat: 'MM-DD-YYYY HH:mm A', - type: 'datetime', - readOnly: 'false' - }); - widget.field.isVisible = false; - fixture.detectChanges(); - expect(element.querySelector('#data-time-widget')).toBeNull(); - widget.fieldChanged.subscribe((field) => { - field.isVisible = true; - fixture.detectChanges(); - fixture.whenStable() - .then(() => { - expect(element.querySelector('#data-time-widget')).toBeDefined(); - expect(element.querySelector('#data-time-widget')).not.toBeNull(); - let dateElement: any = element.querySelector('#date-field-id'); - expect(dateElement.value).toContain('12-30-9999 10:30 AM'); - }); - }); - widget.checkVisibility(widget.field); - })); - - it('should be hided if the visibility change to false', async(() => { - widget.field = new FormFieldModel(new FormModel(), { - id: 'date-field-id', - name: 'date-name', - value: '12-30-9999 10:30 AM', - dateDisplayFormat: 'MM-DD-YYYY HH:mm A', - type: 'datetime', - readOnly: 'false' - }); - fixture.detectChanges(); - expect(element.querySelector('#data-time-widget')).not.toBeNull(); - widget.fieldChanged.subscribe((field) => { - field.isVisible = false; - fixture.detectChanges(); - fixture.whenStable() - .then(() => { - expect(element.querySelector('#data-time-widget')).toBeNull(); - }); - }); - widget.checkVisibility(widget.field); - })); - it('should disable date button when is readonly', async(() => { widget.field = new FormFieldModel(new FormModel(), { id: 'date-field-id', diff --git a/lib/core/form/components/widgets/date-time/date-time.widget.ts b/lib/core/form/components/widgets/date-time/date-time.widget.ts index 1c867fe396..9d2dc70896 100644 --- a/lib/core/form/components/widgets/date-time/date-time.widget.ts +++ b/lib/core/form/components/widgets/date-time/date-time.widget.ts @@ -80,7 +80,7 @@ export class DateTimeWidgetComponent extends WidgetComponent implements OnInit { } else { this.field.value = null; } - this.checkVisibility(this.field); + this.onFieldChanged(this.field); } } diff --git a/lib/core/form/components/widgets/date/date.widget.html b/lib/core/form/components/widgets/date/date.widget.html index 948ea3cf84..a36cc48232 100644 --- a/lib/core/form/components/widgets/date/date.widget.html +++ b/lib/core/form/components/widgets/date/date.widget.html @@ -1,4 +1,4 @@ -
+
{ }); it('should eval visibility on date changed', () => { - spyOn(widget, 'checkVisibility').and.callThrough(); + spyOn(widget, 'onFieldChanged').and.callThrough(); let field = new FormFieldModel(new FormModel(), { id: 'date-field-id', @@ -107,7 +107,7 @@ describe('DateWidgetComponent', () => { widget.field = field; widget.onDateChanged({ value: moment('12/12/2012') }); - expect(widget.checkVisibility).toHaveBeenCalledWith(field); + expect(widget.onFieldChanged).toHaveBeenCalledWith(field); }); describe('template check', () => { @@ -169,45 +169,6 @@ describe('DateWidgetComponent', () => { }); })); - it('should hide not visible date widget', async(() => { - widget.field.isVisible = false; - fixture.detectChanges(); - fixture.whenStable() - .then(() => { - fixture.detectChanges(); - expect(element.querySelector('#data-widget')).toBeNull(); - }); - })); - - it('should become visibile if the visibility change to true', async(() => { - widget.field.isVisible = false; - fixture.detectChanges(); - widget.fieldChanged.subscribe((field) => { - field.isVisible = true; - fixture.detectChanges(); - fixture.whenStable() - .then(() => { - expect(element.querySelector('#date-field-id')).toBeDefined(); - expect(element.querySelector('#date-field-id')).not.toBeNull(); - let dateElement: any = element.querySelector('#date-field-id'); - expect(dateElement.value).toContain('9-9-9999'); - }); - }); - widget.checkVisibility(widget.field); - })); - - it('should be hided if the visibility change to false', async(() => { - widget.fieldChanged.subscribe((field) => { - field.isVisible = false; - fixture.detectChanges(); - fixture.whenStable() - .then(() => { - expect(element.querySelector('#data-widget')).toBeNull(); - }); - }); - widget.checkVisibility(widget.field); - })); - it('should disable date button when is readonly', async(() => { widget.field.readOnly = false; fixture.detectChanges(); diff --git a/lib/core/form/components/widgets/date/date.widget.ts b/lib/core/form/components/widgets/date/date.widget.ts index 2a5f96cece..0a59a02f51 100644 --- a/lib/core/form/components/widgets/date/date.widget.ts +++ b/lib/core/form/components/widgets/date/date.widget.ts @@ -77,7 +77,7 @@ export class DateWidgetComponent extends WidgetComponent implements OnInit { } else { this.field.value = null; } - this.checkVisibility(this.field); + this.onFieldChanged(this.field); } } diff --git a/lib/core/form/components/widgets/dropdown/dropdown.widget.html b/lib/core/form/components/widgets/dropdown/dropdown.widget.html index 5f676b0620..365995c8d7 100644 --- a/lib/core/form/components/widgets/dropdown/dropdown.widget.html +++ b/lib/core/form/components/widgets/dropdown/dropdown.widget.html @@ -1,12 +1,12 @@
+ [class.adf-invalid]="!field.isValid" [class.adf-readonly]="field.readOnly"> + (ngModelChange)="onFieldChanged(field)"> {{opt.name}} diff --git a/lib/core/form/components/widgets/dropdown/dropdown.widget.spec.ts b/lib/core/form/components/widgets/dropdown/dropdown.widget.spec.ts index 9ace0bda14..c587147368 100644 --- a/lib/core/form/components/widgets/dropdown/dropdown.widget.spec.ts +++ b/lib/core/form/components/widgets/dropdown/dropdown.widget.spec.ts @@ -188,27 +188,6 @@ describe('DropdownWidgetComponent', () => { }); })); - it('should be not visible when isVisible is false', async(() => { - widget.field.isVisible = false; - fixture.detectChanges(); - fixture.whenStable() - .then(() => { - let dropDownElement: HTMLSelectElement = element.querySelector('#dropdown-id'); - expect(dropDownElement).toBeNull(); - }); - })); - - it('should became visible when isVisible is true', async(() => { - widget.field.isVisible = false; - fixture.detectChanges(); - expect(element.querySelector('#dropdown-id')).toBeNull(); - widget.field.isVisible = true; - fixture.detectChanges(); - fixture.whenStable() - .then(() => { - expect(element.querySelector('#dropdown-id')).not.toBeNull(); - }); - })); }); describe('and dropdown is populated via processDefinitionId', () => { diff --git a/lib/core/form/components/widgets/dropdown/dropdown.widget.ts b/lib/core/form/components/widgets/dropdown/dropdown.widget.ts index c765d68df8..7cc97978fb 100644 --- a/lib/core/form/components/widgets/dropdown/dropdown.widget.ts +++ b/lib/core/form/components/widgets/dropdown/dropdown.widget.ts @@ -20,7 +20,6 @@ import { LogService } from '../../../../services/log.service'; import { Component, OnInit, ViewEncapsulation } from '@angular/core'; import { FormService } from '../../../services/form.service'; -import { WidgetVisibilityService } from '../../../services/widget-visibility.service'; import { FormFieldOption } from './../core/form-field-option'; import { baseHost , WidgetComponent } from './../widget.component'; @@ -34,7 +33,6 @@ import { baseHost , WidgetComponent } from './../widget.component'; export class DropdownWidgetComponent extends WidgetComponent implements OnInit { constructor(public formService: FormService, - private visibilityService: WidgetVisibilityService, private logService: LogService) { super(formService); } @@ -97,10 +95,6 @@ export class DropdownWidgetComponent extends WidgetComponent implements OnInit { return optionValue; } - checkVisibility() { - this.visibilityService.refreshVisibility(this.field.form); - } - handleError(error: any) { this.logService.error(error); } diff --git a/lib/core/form/components/widgets/dynamic-table/dynamic-table.widget.html b/lib/core/form/components/widgets/dynamic-table/dynamic-table.widget.html index fb453f5381..d17df39eb8 100644 --- a/lib/core/form/components/widgets/dynamic-table/dynamic-table.widget.html +++ b/lib/core/form/components/widgets/dynamic-table/dynamic-table.widget.html @@ -1,5 +1,5 @@
+ [class.adf-invalid]="!isValid()">
{{content.name}}*
diff --git a/lib/core/form/components/widgets/dynamic-table/dynamic-table.widget.spec.ts b/lib/core/form/components/widgets/dynamic-table/dynamic-table.widget.spec.ts index 511af7a664..c489a87006 100644 --- a/lib/core/form/components/widgets/dynamic-table/dynamic-table.widget.spec.ts +++ b/lib/core/form/components/widgets/dynamic-table/dynamic-table.widget.spec.ts @@ -118,7 +118,11 @@ describe('DynamicTableWidgetComponent', () => { element = fixture.nativeElement; widget = fixture.componentInstance; widget.content = table; + widget.field = field; + }); + afterEach(() => { + fixture.destroy(); }); it('should select row on click', () => { diff --git a/lib/core/form/components/widgets/functional-group/functional-group.widget.html b/lib/core/form/components/widgets/functional-group/functional-group.widget.html index 47688ba7b4..cf94ccc7a2 100644 --- a/lib/core/form/components/widgets/functional-group/functional-group.widget.html +++ b/lib/core/form/components/widgets/functional-group/functional-group.widget.html @@ -1,6 +1,6 @@
+ [class.adf-invalid]="!field.isValid" [class.adf-readonly]="field.readOnly" id="functional-group-div"> diff --git a/lib/core/form/components/widgets/number/number.widget.html b/lib/core/form/components/widgets/number/number.widget.html index 06b3e34598..51cbd1f74e 100644 --- a/lib/core/form/components/widgets/number/number.widget.html +++ b/lib/core/form/components/widgets/number/number.widget.html @@ -10,7 +10,7 @@ [required]="isRequired()" [value]="field.value" [(ngModel)]="field.value" - (ngModelChange)="checkVisibility(field)" + (ngModelChange)="onFieldChanged(field)" [disabled]="field.readOnly" placeholder="{{field.placeholder}}"> diff --git a/lib/core/form/components/widgets/people/people.widget.html b/lib/core/form/components/widgets/people/people.widget.html index d2e0795558..386b051e76 100644 --- a/lib/core/form/components/widgets/people/people.widget.html +++ b/lib/core/form/components/widgets/people/people.widget.html @@ -2,8 +2,7 @@ [class.is-dirty]="value" [class.adf-invalid]="!field.isValid" [class.adf-readonly]="field.readOnly" - id="people-widget-content" - *ngIf="field.isVisible"> + id="people-widget-content"> + [class.adf-invalid]="!field.isValid" [class.adf-readonly]="field.readOnly" [id]="field.id">
diff --git a/lib/core/form/components/widgets/radio-buttons/radio-buttons.widget.spec.ts b/lib/core/form/components/widgets/radio-buttons/radio-buttons.widget.spec.ts index 941bd10c4f..7c3734fe8c 100644 --- a/lib/core/form/components/widgets/radio-buttons/radio-buttons.widget.spec.ts +++ b/lib/core/form/components/widgets/radio-buttons/radio-buttons.widget.spec.ts @@ -20,7 +20,6 @@ import { Observable } from 'rxjs/Observable'; import { EcmModelService } from '../../../services/ecm-model.service'; import { FormService } from '../../../services/form.service'; -import { WidgetVisibilityService } from '../../../services/widget-visibility.service'; import { MaterialModule } from '../../../../material.module'; import { ContainerModel } from '../core/container.model'; import { FormFieldTypes } from '../core/form-field-types'; @@ -34,12 +33,10 @@ describe('RadioButtonsWidgetComponent', () => { let formService: FormService; let widget: RadioButtonsWidgetComponent; - let visibilityService: WidgetVisibilityService; beforeEach(() => { formService = new FormService(null, null, null); - visibilityService = new WidgetVisibilityService(null, null); - widget = new RadioButtonsWidgetComponent(formService, visibilityService, null); + widget = new RadioButtonsWidgetComponent(formService, null); widget.field = new FormFieldModel(new FormModel(), { restUrl: '' }); }); @@ -119,8 +116,8 @@ describe('RadioButtonsWidgetComponent', () => { expect(formService.getRestFieldValues).toHaveBeenCalled(); }); - xit('should update the field value when an option is selected', () => { - spyOn(widget, 'checkVisibility').and.stub(); + it('should update the field value when an option is selected', () => { + spyOn(widget, 'onFieldChanged').and.returnValue(Observable.of({})); widget.onOptionClick('fake-opt'); expect(widget.field.value).toEqual('fake-opt'); @@ -131,7 +128,6 @@ describe('RadioButtonsWidgetComponent', () => { let fixture: ComponentFixture; let element: HTMLElement; let stubFormService: FormService; - let stubVisibilityService: WidgetVisibilityService; let restOption: FormFieldOption[] = [{ id: 'opt-1', name: 'opt-name-1' }, { id: 'opt-2', name: 'opt-name-2' @@ -141,7 +137,7 @@ describe('RadioButtonsWidgetComponent', () => { TestBed.configureTestingModule({ imports: [ MaterialModule ], declarations: [RadioButtonsWidgetComponent, ErrorWidgetComponent], - providers: [FormService, EcmModelService, WidgetVisibilityService] + providers: [FormService, EcmModelService] }).compileComponents().then(() => { fixture = TestBed.createComponent(RadioButtonsWidgetComponent); radioButtonWidget = fixture.componentInstance; @@ -158,7 +154,6 @@ describe('RadioButtonsWidgetComponent', () => { beforeEach(async(() => { stubFormService = fixture.debugElement.injector.get(FormService); - stubVisibilityService = fixture.debugElement.injector.get(WidgetVisibilityService); spyOn(stubFormService, 'getRestFieldValues').and.returnValue(Observable.of(restOption)); radioButtonWidget.field = new FormFieldModel(new FormModel({ taskId: 'task-id' }), { id: 'radio-id', @@ -172,7 +167,7 @@ describe('RadioButtonsWidgetComponent', () => { fixture.detectChanges(); })); - it('should show visible radio buttons', async(() => { + it('should show radio buttons', async(() => { expect(element.querySelector('#radio-id')).toBeDefined(); expect(element.querySelector('#radio-id-opt-1-input')).not.toBeNull(); expect(element.querySelector('#radio-id-opt-1')).not.toBeNull(); @@ -180,29 +175,15 @@ describe('RadioButtonsWidgetComponent', () => { expect(element.querySelector('#radio-id-opt-2')).not.toBeNull(); })); - it('should not show invisible radio buttons', async(() => { - radioButtonWidget.field.isVisible = false; - fixture.detectChanges(); - fixture.whenStable() - .then(() => { - expect(element.querySelector('#radio-id')).toBeNull(); - expect(element.querySelector('#radio-id-opt-1-input')).toBeNull(); - expect(element.querySelector('#radio-id-opt-2-input')).toBeNull(); - }); - })); - - it('should evaluate visibility on option click', async(() => { - spyOn(stubVisibilityService, 'evaluateVisibility').and.returnValue(false); + it('should trigger field changed event on click', async(() => { let option: HTMLElement = element.querySelector('#radio-id-opt-1-input'); expect(element.querySelector('#radio-id')).not.toBeNull(); expect(option).not.toBeNull(); option.click(); - fixture.detectChanges(); - fixture.whenStable() - .then(() => { - expect(element.querySelector('#radio-id')).toBeNull(); - expect(element.querySelector('#radio-id-opt-1-input')).toBeNull(); - }); + widget.fieldChanged.subscribe(field => { + expect(element.querySelector('#radio-id')).toBeNull(); + expect(element.querySelector('#radio-id-opt-1-input')).toBeNull(); + }); })); }); diff --git a/lib/core/form/components/widgets/radio-buttons/radio-buttons.widget.ts b/lib/core/form/components/widgets/radio-buttons/radio-buttons.widget.ts index 661cc25fa9..23f48949dc 100644 --- a/lib/core/form/components/widgets/radio-buttons/radio-buttons.widget.ts +++ b/lib/core/form/components/widgets/radio-buttons/radio-buttons.widget.ts @@ -20,7 +20,6 @@ import { LogService } from '../../../../services/log.service'; import { Component, OnInit, ViewEncapsulation } from '@angular/core'; import { FormService } from '../../../services/form.service'; -import { WidgetVisibilityService } from '../../../services/widget-visibility.service'; import { FormFieldOption } from './../core/form-field-option'; import { baseHost , WidgetComponent } from './../widget.component'; @@ -34,7 +33,6 @@ import { baseHost , WidgetComponent } from './../widget.component'; export class RadioButtonsWidgetComponent extends WidgetComponent implements OnInit { constructor(public formService: FormService, - private visibilityService: WidgetVisibilityService, private logService: LogService) { super(formService); } @@ -81,11 +79,7 @@ export class RadioButtonsWidgetComponent extends WidgetComponent implements OnIn onOptionClick(optionSelected: any) { this.field.value = optionSelected; - this.checkVisibility(); - } - - checkVisibility() { - this.visibilityService.refreshVisibility(this.field.form); + this.fieldChanged.emit(this.field); } handleError(error: any) { diff --git a/lib/core/form/components/widgets/typeahead/typeahead.widget.html b/lib/core/form/components/widgets/typeahead/typeahead.widget.html index 36bf52103b..365b0d7077 100644 --- a/lib/core/form/components/widgets/typeahead/typeahead.widget.html +++ b/lib/core/form/components/widgets/typeahead/typeahead.widget.html @@ -3,7 +3,7 @@ [class.is-dirty]="value" [class.adf-invalid]="!field.isValid" [class.adf-readonly]="field.readOnly" - id="typehead-div" *ngIf="field.isVisible"> + id="typehead-div"> { let formService: FormService; let widget: TypeaheadWidgetComponent; - let visibilityService: WidgetVisibilityService; beforeEach(() => { formService = new FormService(null, null, null); - visibilityService = new WidgetVisibilityService(null, null); - widget = new TypeaheadWidgetComponent(formService, visibilityService, null); + widget = new TypeaheadWidgetComponent(formService, null); widget.field = new FormFieldModel(new FormModel({ taskId: 'task-id' })); + widget.field.restUrl = 'whateverURL'; }); it('should request field values from service', () => { @@ -52,7 +50,8 @@ describe('TypeaheadWidgetComponent', () => { }); widget.field = new FormFieldModel(form, { - id: fieldId + id: fieldId, + restUrl: 'whateverURL' }); spyOn(formService, 'getRestFieldValues').and.returnValue(Observable.create(observer => { @@ -63,6 +62,23 @@ describe('TypeaheadWidgetComponent', () => { expect(formService.getRestFieldValues).toHaveBeenCalledWith(taskId, fieldId); }); + it('should not perform any request if restUrl is not present', () => { + const taskId = ''; + const fieldId = ''; + + let form = new FormModel({ + taskId: taskId + }); + + widget.field = new FormFieldModel(form, { + id: fieldId + }); + + spyOn(formService, 'getRestFieldValues'); + widget.ngOnInit(); + expect(formService.getRestFieldValues).not.toHaveBeenCalled(); + }); + it('should handle error when requesting fields with task id', () => { const taskId = ''; const fieldId = ''; @@ -72,7 +88,8 @@ describe('TypeaheadWidgetComponent', () => { }); widget.field = new FormFieldModel(form, { - id: fieldId + id: fieldId, + restUrl: 'whateverURL' }); const err = 'Error'; spyOn(formService, 'getRestFieldValues').and.returnValue(Observable.throw(err)); @@ -93,7 +110,8 @@ describe('TypeaheadWidgetComponent', () => { }); widget.field = new FormFieldModel(form, { - id: fieldId + id: fieldId, + restUrl: 'whateverURL' }); const err = 'Error'; spyOn(formService, 'getRestFieldValuesByProcessId').and.returnValue(Observable.throw(err)); @@ -114,6 +132,7 @@ describe('TypeaheadWidgetComponent', () => { observer.complete(); })); widget.field.value = '2'; + widget.field.restUrl = 'whateverURL'; widget.ngOnInit(); expect(formService.getRestFieldValues).toHaveBeenCalled(); @@ -130,6 +149,7 @@ describe('TypeaheadWidgetComponent', () => { })); widget.field.value = '3'; + widget.field.restUrl = 'whateverURL'; widget.ngOnInit(); expect(formService.getRestFieldValues).toHaveBeenCalled(); @@ -156,6 +176,7 @@ describe('TypeaheadWidgetComponent', () => { observer.next([]); observer.complete(); })); + widget.field.restUrl = 'whateverURL'; spyOn(widget.field, 'updateForm').and.callThrough(); widget.ngOnInit(); @@ -205,7 +226,7 @@ describe('TypeaheadWidgetComponent', () => { TestBed.configureTestingModule({ imports: [MaterialModule], declarations: [TypeaheadWidgetComponent, ErrorWidgetComponent], - providers: [ FormService, EcmModelService, WidgetVisibilityService ] + providers: [ FormService, EcmModelService] }).compileComponents().then(() => { fixture = TestBed.createComponent(TypeaheadWidgetComponent); typeaheadWidgetComponent = fixture.componentInstance; @@ -249,14 +270,13 @@ describe('TypeaheadWidgetComponent', () => { 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)); typeaheadWidgetComponent.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), { id: 'typeahead-id', name: 'typeahead-name', type: FormFieldTypes.TYPEAHEAD, - readOnly: false + readOnly: false, + restUrl: 'whateverURL' }); typeaheadWidgetComponent.field.isVisible = true; fixture.detectChanges(); @@ -322,22 +342,12 @@ describe('TypeaheadWidgetComponent', () => { expect(element.querySelector('.adf-error-text').textContent).toContain('FORM.FIELD.VALIDATOR.INVALID_VALUE'); }); })); - - it('should hide not visible typeahead', async(() => { - typeaheadWidgetComponent.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)); typeaheadWidgetComponent.field = new FormFieldModel(new FormModel({ processDefinitionId: 'fake-process-id' }), { id: 'typeahead-id', diff --git a/lib/core/form/components/widgets/typeahead/typeahead.widget.ts b/lib/core/form/components/widgets/typeahead/typeahead.widget.ts index f5cd49ab1f..86f5b51e43 100644 --- a/lib/core/form/components/widgets/typeahead/typeahead.widget.ts +++ b/lib/core/form/components/widgets/typeahead/typeahead.widget.ts @@ -20,7 +20,6 @@ import { LogService } from '../../../../services/log.service'; import { ENTER, ESCAPE } from '@angular/cdk/keycodes'; import { Component, OnInit, ViewEncapsulation } from '@angular/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'; @@ -40,15 +39,14 @@ export class TypeaheadWidgetComponent extends WidgetComponent implements OnInit options: FormFieldOption[] = []; constructor(public formService: FormService, - private visibilityService: WidgetVisibilityService, private logService: LogService) { super(formService); } ngOnInit() { - if (this.field.form.taskId) { + if (this.field.form.taskId && this.field.restUrl) { this.getValuesByTaskId(); - } else if (this.field.form.processDefinitionId) { + } else if (this.field.form.processDefinitionId && this.field.restUrl) { this.getValuesByProcessDefinitionId(); } if (this.isReadOnlyType()) { @@ -74,8 +72,8 @@ export class TypeaheadWidgetComponent extends WidgetComponent implements OnInit this.value = toSelect.name; } } + this.onFieldChanged(this.field); this.field.updateForm(); - this.visibilityService.refreshEntityVisibility(this.field); }, err => this.handleError(err) ); @@ -99,8 +97,8 @@ export class TypeaheadWidgetComponent extends WidgetComponent implements OnInit this.value = toSelect.name; } } + this.onFieldChanged(this.field); this.field.updateForm(); - this.visibilityService.refreshEntityVisibility(this.field); }, err => this.handleError(err) ); @@ -141,7 +139,7 @@ export class TypeaheadWidgetComponent extends WidgetComponent implements OnInit if (item) { this.field.value = item.id; this.value = item.name; - this.checkVisibility(); + this.onFieldChanged(this.field); } } @@ -157,10 +155,6 @@ export class TypeaheadWidgetComponent extends WidgetComponent implements OnInit this.logService.error(error); } - checkVisibility() { - this.visibilityService.refreshVisibility(this.field.form); - } - isReadOnlyType(): boolean { return this.field.type === 'readonly' ? true : false; } diff --git a/lib/core/form/components/widgets/widget.component.spec.ts b/lib/core/form/components/widgets/widget.component.spec.ts index d41ff37cc3..286027bd7b 100644 --- a/lib/core/form/components/widgets/widget.component.spec.ts +++ b/lib/core/form/components/widgets/widget.component.spec.ts @@ -93,7 +93,7 @@ describe('WidgetComponent', () => { done(); }); - widget.checkVisibility(fakeField); + widget.onFieldChanged(fakeField); }); it('should eval isRequired state of the field', () => {