From e99b48a6da3cd513f693362203693e1c4efd1058 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Wed, 14 Sep 2016 18:01:53 +0100 Subject: [PATCH] #726 dropdown and typeahead validation fixes #743 --- .../widgets/core/form-field-validator.ts | 13 +++++++- .../widgets/core/form-field.model.ts | 20 +++++++++---- .../widgets/dropdown/dropdown.widget.css | 18 ++++++++++- .../widgets/dropdown/dropdown.widget.html | 10 +++++-- .../widgets/dropdown/dropdown.widget.spec.ts | 3 +- .../widgets/dropdown/dropdown.widget.ts | 30 +++++++++++-------- .../widgets/number/number.widget.html | 1 - .../widgets/typeahead/typeahead.widget.css | 18 +++++++++++ .../widgets/typeahead/typeahead.widget.html | 5 ++-- .../widgets/typeahead/typeahead.widget.ts | 5 +++- 10 files changed, 96 insertions(+), 27 deletions(-) diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/core/form-field-validator.ts b/ng2-components/ng2-activiti-form/src/components/widgets/core/form-field-validator.ts index ba4661834c..496079aab4 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/core/form-field-validator.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/core/form-field-validator.ts @@ -30,7 +30,9 @@ export class RequiredFieldValidator implements FormFieldValidator { private supportedTypes = [ FormFieldTypes.TEXT, FormFieldTypes.MULTILINE_TEXT, - FormFieldTypes.NUMBER + FormFieldTypes.NUMBER, + FormFieldTypes.TYPEAHEAD, + FormFieldTypes.DROPDOWN ]; isSupported(field: FormFieldModel): boolean { @@ -41,6 +43,15 @@ export class RequiredFieldValidator implements FormFieldValidator { validate(field: FormFieldModel): boolean { if (this.isSupported(field)) { + + if (field.type === FormFieldTypes.DROPDOWN) { + if (field.hasEmptyValue && field.emptyOption) { + if (field.value === field.emptyOption.id) { + return false; + } + } + } + if (!field.value) { return false; } 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 e50c266b9c..e62eaaafb1 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 @@ -66,6 +66,7 @@ export class FormFieldModel extends FormWidgetModel { isVisible: boolean = true; visibilityCondition: WidgetVisibilityModel = null; + emptyOption: FormFieldOption; validationSummary: string; validators: FormFieldValidator[] = []; @@ -137,9 +138,11 @@ export class FormFieldModel extends FormWidgetModel { this.hyperlinkUrl = json.hyperlinkUrl; this.displayText = json.displayText; this.visibilityCondition = json.visibilityCondition; - this._value = this.parseValue(json); - this.updateForm(); + } + + if (this.hasEmptyValue && this.options && this.options.length > 0) { + this.emptyOption = this.options[0]; } this.validators = [ @@ -151,6 +154,8 @@ export class FormFieldModel extends FormWidgetModel { new MaxValueFieldValidator(), new RegExFieldValidator() ]; + + this.updateForm(); } parseValue(json: any): any { @@ -160,10 +165,15 @@ export class FormFieldModel extends FormWidgetModel { This is needed due to Activiti issue related to reading dropdown values as value string but saving back as object: { id: , name: } */ - // TODO: needs review if (json.type === FormFieldTypes.DROPDOWN) { - if (value === '') { - value = 'empty'; + if (json.hasEmptyValue && json.options) { + let options = json.options || []; + if (options.length > 0) { + let emptyOption = json.options[0]; + if (value === '' || value === emptyOption.id || value === emptyOption.name) { + value = emptyOption.id; + } + } } } diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/dropdown/dropdown.widget.css b/ng2-components/ng2-activiti-form/src/components/widgets/dropdown/dropdown.widget.css index f1be2ed3ba..ae995ca854 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/dropdown/dropdown.widget.css +++ b/ng2-components/ng2-activiti-form/src/components/widgets/dropdown/dropdown.widget.css @@ -2,6 +2,22 @@ width: 100%; } -.dropdown-widget > select { +.dropdown-widget__select { width: 100%; } + +.dropdown-widget__invalid .dropdown-widget__select { + border-color: #d50000; +} + +.dropdown-widget__invalid .dropdown-widget__label { + color: #d50000; +} + +.dropdown-widget__invalid .dropdown-widget__label:after { + background-color: #d50000; +} + +.dropdown-widget__invalid .mdl-textfield__error { + visibility: visible !important; +} diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/dropdown/dropdown.widget.html b/ng2-components/ng2-activiti-form/src/components/widgets/dropdown/dropdown.widget.html index a6c3d50a94..8032eb3e71 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/dropdown/dropdown.widget.html +++ b/ng2-components/ng2-activiti-form/src/components/widgets/dropdown/dropdown.widget.html @@ -1,6 +1,10 @@ - diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/dropdown/dropdown.widget.spec.ts b/ng2-components/ng2-activiti-form/src/components/widgets/dropdown/dropdown.widget.spec.ts index 292ffd54dc..272e43b68c 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/dropdown/dropdown.widget.spec.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/dropdown/dropdown.widget.spec.ts @@ -42,7 +42,8 @@ describe('DropdownWidget', () => { }); widget.field = new FormFieldModel(form, { - id: fieldId + id: fieldId, + restUrl: '' }); spyOn(formService, 'getRestFieldValues').and.returnValue(Observable.create(observer => { diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/dropdown/dropdown.widget.ts b/ng2-components/ng2-activiti-form/src/components/widgets/dropdown/dropdown.widget.ts index b3811a2e42..7aebd23bae 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/dropdown/dropdown.widget.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/dropdown/dropdown.widget.ts @@ -36,18 +36,24 @@ export class DropdownWidget extends WidgetComponent implements OnInit { } ngOnInit() { - this.formService - .getRestFieldValues( - this.field.form.taskId, - this.field.id - ) - .subscribe( - (result: FormFieldOption[]) => { - this.field.options = result || []; - this.field.updateForm(); - }, - this.handleError - ); + if (this.field && this.field.restUrl) { + this.formService + .getRestFieldValues( + this.field.form.taskId, + this.field.id + ) + .subscribe( + (result: FormFieldOption[]) => { + let options = []; + if (this.field.emptyOption) { + options.push(this.field.emptyOption); + } + this.field.options = options.concat((result || [])); + this.field.updateForm(); + }, + this.handleError + ); + } } handleError(error: any) { diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/number/number.widget.html b/ng2-components/ng2-activiti-form/src/components/widgets/number/number.widget.html index b5b880f7d1..3b0736f377 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/number/number.widget.html +++ b/ng2-components/ng2-activiti-form/src/components/widgets/number/number.widget.html @@ -9,6 +9,5 @@ (ngModelChange)="checkVisibility(field)" [disabled]="field.readOnly"> - {{field.validationSummary}} diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/typeahead/typeahead.widget.css b/ng2-components/ng2-activiti-form/src/components/widgets/typeahead/typeahead.widget.css index 5cefa1e623..31b3776aae 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/typeahead/typeahead.widget.css +++ b/ng2-components/ng2-activiti-form/src/components/widgets/typeahead/typeahead.widget.css @@ -27,3 +27,21 @@ .typeahead-autocomplete > ul > li { opacity: 1; } + + + +.typeahead-widget__invalid .mdl-textfield__input { + border-color: #d50000; +} + +.typeahead-widget__invalid .mdl-textfield__label { + color: #d50000; +} + +.typeahead-widget__invalid .mdl-textfield__label:after { + background-color: #d50000; +} + +.typeahead-widget__invalid .mdl-textfield__error { + visibility: visible !important; +} diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/typeahead/typeahead.widget.html b/ng2-components/ng2-activiti-form/src/components/widgets/typeahead/typeahead.widget.html index 332465da94..f2416b7700 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/typeahead/typeahead.widget.html +++ b/ng2-components/ng2-activiti-form/src/components/widgets/typeahead/typeahead.widget.html @@ -1,5 +1,6 @@
+ [class.is-dirty]="value" + [class.typeahead-widget__invalid]="!field.isValid"> + {{field.validationSummary}}
-
  • item.name.toLocaleLowerCase() === this.value.toLocaleLowerCase()); + 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; @@ -100,6 +102,7 @@ export class TypeaheadWidget extends WidgetComponent implements OnInit { this.value = null; } + // TODO: seems to be not needed as field.value setter calls it this.field.updateForm(); }