@@ -19,9 +20,9 @@
diff --git a/ng2-components/ng2-activiti-form/src/components/activiti-form.component.spec.ts b/ng2-components/ng2-activiti-form/src/components/activiti-form.component.spec.ts
index 37204d11d6..3f3497c3ae 100644
--- a/ng2-components/ng2-activiti-form/src/components/activiti-form.component.spec.ts
+++ b/ng2-components/ng2-activiti-form/src/components/activiti-form.component.spec.ts
@@ -98,13 +98,13 @@ describe('ActivitiForm', () => {
});
it('should not enable outcome button when model missing', () => {
- expect(formComponent.isOutcomeButtonEnabled(null)).toBeFalsy();
+ expect(formComponent.isOutcomeButtonVisible(null)).toBeFalsy();
});
it('should enable custom outcome buttons', () => {
let formModel = new FormModel();
let outcome = new FormOutcomeModel(formModel, { id: 'action1', name: 'Action 1' });
- expect(formComponent.isOutcomeButtonEnabled(outcome)).toBeTruthy();
+ expect(formComponent.isOutcomeButtonVisible(outcome)).toBeTruthy();
});
@@ -113,10 +113,10 @@ describe('ActivitiForm', () => {
let outcome = new FormOutcomeModel(formModel, { id: '$save', name: FormOutcomeModel.SAVE_ACTION });
formComponent.showSaveButton = true;
- expect(formComponent.isOutcomeButtonEnabled(outcome)).toBeTruthy();
+ expect(formComponent.isOutcomeButtonVisible(outcome)).toBeTruthy();
formComponent.showSaveButton = false;
- expect(formComponent.isOutcomeButtonEnabled(outcome)).toBeFalsy();
+ expect(formComponent.isOutcomeButtonVisible(outcome)).toBeFalsy();
});
it('should allow controlling [save] button visibility', () => {
@@ -124,10 +124,10 @@ describe('ActivitiForm', () => {
let outcome = new FormOutcomeModel(formModel, { id: '$save', name: FormOutcomeModel.COMPLETE_ACTION });
formComponent.showCompleteButton = true;
- expect(formComponent.isOutcomeButtonEnabled(outcome)).toBeTruthy();
+ expect(formComponent.isOutcomeButtonVisible(outcome)).toBeTruthy();
formComponent.showCompleteButton = false;
- expect(formComponent.isOutcomeButtonEnabled(outcome)).toBeFalsy();
+ expect(formComponent.isOutcomeButtonVisible(outcome)).toBeFalsy();
});
it('should load form on refresh', () => {
diff --git a/ng2-components/ng2-activiti-form/src/components/activiti-form.component.ts b/ng2-components/ng2-activiti-form/src/components/activiti-form.component.ts
index d8d4c61755..721bd0a45b 100644
--- a/ng2-components/ng2-activiti-form/src/components/activiti-form.component.ts
+++ b/ng2-components/ng2-activiti-form/src/components/activiti-form.component.ts
@@ -128,7 +128,7 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges {
showSaveButton: boolean = true;
@Input()
- showDebugButton: boolean = false;
+ showDebugButton: boolean = true;
@Input()
readOnly: boolean = false;
@@ -175,6 +175,21 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges {
}
isOutcomeButtonEnabled(outcome: FormOutcomeModel): boolean {
+ if (this.form.readOnly) {
+ return false;
+ }
+
+ if (outcome) {
+ // Make 'Save' button always available
+ if (outcome.name === FormOutcomeModel.SAVE_ACTION) {
+ return true;
+ }
+ return this.form.isValid;
+ }
+ return false;
+ }
+
+ isOutcomeButtonVisible(outcome: FormOutcomeModel): boolean {
if (outcome && outcome.name) {
if (outcome.name === FormOutcomeModel.COMPLETE_ACTION) {
return this.showCompleteButton;
diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/core/form-field.model.ts b/ng2-components/ng2-activiti-form/src/components/widgets/core/form-field.model.ts
index 365a669dcc..44b0eccad8 100644
--- a/ng2-components/ng2-activiti-form/src/components/widgets/core/form-field.model.ts
+++ b/ng2-components/ng2-activiti-form/src/components/widgets/core/form-field.model.ts
@@ -65,6 +65,17 @@ export class FormFieldModel extends FormWidgetModel {
return this._readOnly;
}
+ isValid(): boolean {
+
+ if (this.required) {
+ if (this.type === FormFieldTypes.TEXT || this.type === FormFieldTypes.MULTILINE_TEXT) {
+ return this._value ? true : false;
+ }
+ }
+
+ return true;
+ }
+
constructor(form: FormModel, json?: any) {
super(form, json);
@@ -129,7 +140,6 @@ export class FormFieldModel extends FormWidgetModel {
}
updateForm() {
-
switch (this.type) {
case FormFieldTypes.DROPDOWN:
/*
@@ -177,5 +187,7 @@ export class FormFieldModel extends FormWidgetModel {
this.form.values[this.id] = this.value;
}
}
+
+ this.form.onFormFieldChanged(this);
}
}
diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/core/form.model.ts b/ng2-components/ng2-activiti-form/src/components/widgets/core/form.model.ts
index 00f72226f5..4bd7946aba 100644
--- a/ng2-components/ng2-activiti-form/src/components/widgets/core/form.model.ts
+++ b/ng2-components/ng2-activiti-form/src/components/widgets/core/form.model.ts
@@ -20,6 +20,7 @@ import { FormValues } from './form-values';
import { ContainerModel } from './container.model';
import { TabModel } from './tab.model';
import { FormOutcomeModel } from './form-outcome.model';
+import { FormFieldModel } from './form-field.model';
export class FormModel {
@@ -31,6 +32,7 @@ export class FormModel {
private _name: string;
private _taskId: string;
private _taskName: string = FormModel.UNSET_TASK_NAME;
+ private _isValid: boolean = true;
get id(): string {
return this._id;
@@ -48,6 +50,10 @@ export class FormModel {
return this._taskName;
}
+ get isValid(): boolean {
+ return this._isValid;
+ }
+
readOnly: boolean = false;
tabs: TabModel[] = [];
fields: ContainerModel[] = [];
@@ -102,7 +108,8 @@ export class FormModel {
if (field.tab) {
let tab = tabCache[field.tab];
if (tab) {
- tab.fields.push(new ContainerModel(this, field.json));
+ // tab.fields.push(new ContainerModel(this, field.json));
+ tab.fields.push(field);
}
}
}
@@ -119,6 +126,48 @@ export class FormModel {
}
}
+ onFormFieldChanged(field: FormFieldModel) {
+ this.validateField(field);
+ }
+
+ // TODO: evaluate and cache once the form is loaded
+ private getFormFields(): FormFieldModel[] {
+ let result: FormFieldModel[] = [];
+
+ for (let i = 0; i < this.fields.length; i++) {
+ let container = this.fields[i];
+ for (let j = 0; j < container.columns.length; j++) {
+ let column = container.columns[j];
+ for (let k = 0; k < column.fields.length; k++) {
+ let field = column.fields[k];
+ result.push(field);
+ }
+ }
+ }
+
+ return result;
+ }
+
+ private validateForm() {
+ this._isValid = true;
+ let fields = this.getFormFields();
+ for (let i = 0; i < fields.length; i++) {
+ if (!fields[i].isValid()) {
+ this._isValid = false;
+ return;
+ }
+ }
+ }
+
+ private validateField(field: FormFieldModel) {
+ if (!field) return;
+ if (!field.isValid()) {
+ this._isValid = false;
+ return;
+ }
+ this.validateForm();
+ }
+
private parseContainerFields(json: any): ContainerModel[] {
let fields = [];
diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/multiline-text/multiline-text.widget.html b/ng2-components/ng2-activiti-form/src/components/widgets/multiline-text/multiline-text.widget.html
index 2511b63434..a79dd93ef9 100644
--- a/ng2-components/ng2-activiti-form/src/components/widgets/multiline-text/multiline-text.widget.html
+++ b/ng2-components/ng2-activiti-form/src/components/widgets/multiline-text/multiline-text.widget.html
@@ -3,6 +3,7 @@
type="text"
rows= "3"
[attr.id]="field.id"
+ [attr.required]="isRequired()"
[(ngModel)]="field.value"
(ngModelChange)="checkVisibility(field)"
[disabled]="field.readOnly">
diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/text/text.widget.html b/ng2-components/ng2-activiti-form/src/components/widgets/text/text.widget.html
index d74aac765a..67e0a654ce 100644
--- a/ng2-components/ng2-activiti-form/src/components/widgets/text/text.widget.html
+++ b/ng2-components/ng2-activiti-form/src/components/widgets/text/text.widget.html
@@ -2,6 +2,7 @@
diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/widget.component.ts b/ng2-components/ng2-activiti-form/src/components/widgets/widget.component.ts
index b27efe1214..6bdaa17faa 100644
--- a/ng2-components/ng2-activiti-form/src/components/widgets/widget.component.ts
+++ b/ng2-components/ng2-activiti-form/src/components/widgets/widget.component.ts
@@ -36,6 +36,13 @@ export class WidgetComponent implements AfterViewInit {
return this.field ? true : false;
}
+ isRequired(): any {
+ if (this.field && this.field.required) {
+ return true;
+ }
+ return null;
+ }
+
ngAfterViewInit() {
this.setupMaterialComponents();
this.fieldChanged.emit(this.field);