From fe7b05df4f4d245367ccfeecaf3e9457eff9a06c Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Tue, 25 Oct 2016 11:49:43 +0100 Subject: [PATCH] Basic input validation (dynamic table) --- .../widgets/core/dynamic-table.model.ts | 112 ++++++++++++++++++ .../dynamic-table/dynamic-table.widget.css | 4 - .../dynamic-table/dynamic-table.widget.html | 51 ++------ .../dynamic-table/dynamic-table.widget.ts | 2 + .../editors/boolean/boolean.editor.html | 2 + .../editors/date/date.editor.html | 2 + .../editors/dropdown/dropdown.editor.html | 6 +- .../editors/dropdown/dropdown.editor.ts | 37 +++--- .../dynamic-table/editors/row.editor.css | 16 +++ .../dynamic-table/editors/row.editor.html | 45 +++++++ .../dynamic-table/editors/row.editor.ts | 73 ++++++++++++ .../editors/text/text.editor.css | 3 + .../editors/text/text.editor.html | 4 +- .../src/components/widgets/index.ts | 5 +- 14 files changed, 293 insertions(+), 69 deletions(-) create mode 100644 ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/editors/row.editor.css create mode 100644 ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/editors/row.editor.html create mode 100644 ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/editors/row.editor.ts diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/core/dynamic-table.model.ts b/ng2-components/ng2-activiti-form/src/components/widgets/core/dynamic-table.model.ts index 7b4ec221dd..8c6e748848 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/core/dynamic-table.model.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/core/dynamic-table.model.ts @@ -29,6 +29,7 @@ export class DynamicTableModel extends FormWidgetModel { rows: DynamicTableRow[] = []; private _selectedRow: DynamicTableRow; + private _validators: CellValidator[] = []; get selectedRow(): DynamicTableRow { return this._selectedRow; @@ -65,6 +66,11 @@ export class DynamicTableModel extends FormWidgetModel { this.rows = json.value.map(obj => { selected: false, value: obj }); } } + + this._validators = [ + new RequiredCellValidator(), + new NumberCellValidator() + ]; } flushValue() { @@ -112,6 +118,25 @@ export class DynamicTableModel extends FormWidgetModel { } } + validateRow(row: DynamicTableRow): DynamicRowValidationSummary { + let summary = { + isValid: true, + text: null + }; + + if (row) { + for (let col of this.columns) { + for (let validator of this._validators) { + if (!validator.validate(row, col, summary)) { + return summary; + } + } + } + } + + return summary; + } + getCellValue(row: DynamicTableRow, column: DynamicTableColumn): any { let result = row.value[column.id]; @@ -134,3 +159,90 @@ export class DynamicTableModel extends FormWidgetModel { return result || ''; } } + +export interface DynamicRowValidationSummary { + + isValid: boolean; + text: string; + +} + +export interface CellValidator { + + isSupported(column: DynamicTableColumn): boolean; + validate(row: DynamicTableRow, column: DynamicTableColumn, summary?: DynamicRowValidationSummary): boolean; + +} + +export class RequiredCellValidator implements CellValidator { + + private supportedTypes: string[] = [ + 'String', + 'Number', + 'Amount', + 'Date', + 'Dropdown' + ]; + + isSupported(column: DynamicTableColumn): boolean { + return column && column.required && this.supportedTypes.indexOf(column.type) > -1; + } + + validate(row: DynamicTableRow, column: DynamicTableColumn, summary?: DynamicRowValidationSummary): boolean { + if (this.isSupported(column)) { + let value = row.value[column.id]; + if (column.required) { + if (value === null || value === undefined || value === '') { + if (summary) { + summary.isValid = false; + summary.text = `Field '${column.name}' is required.`; + } + return false; + } + } + } + + return true; + } + +} + +export class NumberCellValidator implements CellValidator { + + private supportedTypes: string[] = [ + 'Number', + 'Amount' + ]; + + isSupported(column: DynamicTableColumn): boolean { + return column && column.required && this.supportedTypes.indexOf(column.type) > -1; + } + + isNumber(value: any): boolean { + if (value === null || value === undefined || value === '') { + return false; + } + + return !isNaN(+value); + } + + validate(row: DynamicTableRow, column: DynamicTableColumn, summary?: DynamicRowValidationSummary): boolean { + + if (this.isSupported(column)) { + let value = row.value[column.id]; + if (value === null || + value === undefined || + value === '' || + this.isNumber(value)) { + return true; + } + + if (summary) { + summary.isValid = false; + summary.text = `Field '${column.name}' must be a number.`; + } + return false; + } + return true; + } +} diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/dynamic-table.widget.css b/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/dynamic-table.widget.css index 58fad7d660..7f133c4f0a 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/dynamic-table.widget.css +++ b/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/dynamic-table.widget.css @@ -11,10 +11,6 @@ width: 100%; } -.dynamic-table-widget__table-editor { - width: 100%; -} - .dynamic-table-widget__invalid .mdl-textfield__input { border-color: #d50000; } diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/dynamic-table.widget.html b/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/dynamic-table.widget.html index fd4f081758..dd39213e6c 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/dynamic-table.widget.html +++ b/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/dynamic-table.widget.html @@ -51,49 +51,12 @@ -
-
-
-
- - -
-
- - -
+ + -
- - -
-
- - -
-
-
-
- - -
-
- - diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/dynamic-table.widget.ts b/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/dynamic-table.widget.ts index 1969189bd6..2eeddbc277 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/dynamic-table.widget.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/dynamic-table.widget.ts @@ -32,12 +32,14 @@ export class DynamicTableWidget extends WidgetComponent implements OnInit { editMode: boolean; editRow: DynamicTableRow; + validationSummary: string; constructor(private elementRef: ElementRef) { super(); } ngOnInit() { + this.validationSummary = 'hello world'; } onRowClicked(row: DynamicTableRow) { diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/editors/boolean/boolean.editor.html b/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/editors/boolean/boolean.editor.html index 88488cc509..b92d6f30ba 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/editors/boolean/boolean.editor.html +++ b/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/editors/boolean/boolean.editor.html @@ -4,6 +4,8 @@ type="checkbox" [attr.id]="column.id" [checked]="table.getCellValue(row, column)" + [required]="column.required" + [disabled]="!column.editable" (change)="onValueChanged(row, column, $event)"> {{column.name}} diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/editors/date/date.editor.html b/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/editors/date/date.editor.html index 64e481278c..b4beaa2463 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/editors/date/date.editor.html +++ b/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/editors/date/date.editor.html @@ -7,6 +7,8 @@ [value]="table.getCellValue(row, column)" [attr.id]="column.id" [readonly]="true" + [required]="column.required" + [disabled]="!column.editable" (onOk)="onDateSelected($event)"> diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/editors/dropdown/dropdown.editor.html b/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/editors/dropdown/dropdown.editor.html index 33f2045b1a..026f9cd555 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/editors/dropdown/dropdown.editor.html +++ b/ng2-components/ng2-activiti-form/src/components/widgets/dynamic-table/editors/dropdown/dropdown.editor.html @@ -1,9 +1,11 @@ -
+