Browse Source

Add min/max validation

pull/3561/head
Chantsova Ekaterina 6 years ago
parent
commit
bb06f5ebe0
  1. 11
      ui-ngx/src/app/modules/home/components/widget/lib/multiple-input-widget.component.html
  2. 39
      ui-ngx/src/app/modules/home/components/widget/lib/multiple-input-widget.component.ts
  3. 3
      ui-ngx/src/assets/locale/locale.constant-en_US.json

11
ui-ngx/src/app/modules/home/components/widget/lib/multiple-input-widget.component.html

@ -53,12 +53,20 @@
[readonly]="key.settings.isEditable === 'readonly'"
type="number"
step="{{key.settings.step}}"
min="{{key.settings.minValue}}"
max="{{key.settings.maxValue}}"
(focus)="key.isFocused = true; focusInputElement($event)"
(blur)="key.isFocused = false; inputChanged(source, key)">
<mat-icon *ngIf="key.settings.icon" matPrefix>{{key.settings.icon}}</mat-icon>
<mat-error *ngIf="multipleInputFormGroup.get(key.formId).hasError('required')">
{{key.settings.requiredErrorMessage}}
</mat-error>
<mat-error *ngIf="multipleInputFormGroup.get(key.formId).hasError('min')">
{{ 'widgets.input-widgets.min-value-error' | translate:{value: key.settings.minValue} }}
</mat-error>
<mat-error *ngIf="multipleInputFormGroup.get(key.formId).hasError('max')">
{{ 'widgets.input-widgets.max-value-error' | translate:{value: key.settings.maxValue} }}
</mat-error>
</mat-form-field>
</div>
<div class="input-field mat-block" *ngIf="key.settings.dataKeyValueType === 'booleanCheckbox'">
@ -92,6 +100,9 @@
<mat-error *ngIf="multipleInputFormGroup.get(key.formId).hasError('required')">
{{key.settings.requiredErrorMessage}}
</mat-error>
<mat-error *ngIf="multipleInputFormGroup.get(key.formId).hasError('matDatepickerParse')">
{{ 'widgets.input-widgets.invalid-date' | translate }}
</mat-error>
</mat-form-field>
</div>
</div>

39
ui-ngx/src/app/modules/home/components/widget/lib/multiple-input-widget.component.ts

@ -24,7 +24,7 @@ import { UtilsService } from '@core/services/utils.service';
import { TranslateService } from '@ngx-translate/core';
import { DataKey, Datasource, DatasourceData, DatasourceType, WidgetConfig } from '@shared/models/widget.models';
import { IWidgetSubscription } from '@core/api/widget-api.models';
import { isDefined, isEqual, isUndefined, createLabelFromDatasource } from '@core/utils';
import { isDefined, isEqual, isUndefined, createLabelFromDatasource, isDefinedAndNotNull } from '@core/utils';
import { EntityType } from '@shared/models/entity-type.models';
import * as _moment from 'moment';
import { FormBuilder, FormGroup, ValidatorFn, Validators } from '@angular/forms';
@ -62,19 +62,32 @@ interface MultipleInputWidgetDataKeySettings {
isEditable: MultipleInputWidgetDataKeyEditableType;
disabledOnDataKey: string;
dataKeyHidden: boolean;
step: number;
requiredErrorMessage: string;
step?: number;
minValue?: number;
maxValue?: number;
requiredErrorMessage?: string;
invalidDateErrorMessage?: string;
minErrorMessage?: string;
maxErrorMessage?: string;
icon: string;
inputTypeNumber?: boolean;
readOnly?: boolean;
disabledOnCondition?: boolean;
}
interface MultipleInputWidgetDataKeyErrorMessages {
requiredErrorMessage?: string;
invalidDateErrorMessage?: string;
minErrorMessage?: string;
maxErrorMessage?: string;
}
interface MultipleInputWidgetDataKey extends DataKey {
formId?: string;
settings: MultipleInputWidgetDataKeySettings;
isFocused: boolean;
value?: any;
errorMessages?: MultipleInputWidgetDataKeyErrorMessages;
}
interface MultipleInputWidgetSource {
@ -195,7 +208,7 @@ export class MultipleInputWidgetComponent extends PageComponent implements OnIni
if (dataKey.units) {
dataKey.label += ' (' + dataKey.units + ')';
}
dataKey.formId = (++keyIndex)+'';
dataKey.formId = (++keyIndex) + '';
dataKey.isFocused = false;
// For backward compatibility
@ -245,6 +258,14 @@ export class MultipleInputWidgetComponent extends PageComponent implements OnIni
if (key.settings.dataKeyValueType === 'integer') {
validators.push(Validators.pattern(/^-?[0-9]+$/));
}
if (key.settings.dataKeyValueType === 'integer' || key.settings.dataKeyValueType === 'double') {
if (isDefinedAndNotNull(key.settings.minValue) && isFinite(key.settings.minValue)) {
validators.push(Validators.min(key.settings.minValue));
}
if (isDefinedAndNotNull(key.settings.maxValue) && isFinite(key.settings.maxValue)) {
validators.push(Validators.max(key.settings.maxValue));
}
}
const formControl = this.fb.control(
{ value: key.value,
disabled: key.settings.isEditable === 'disabled' || key.settings.disabledOnCondition},
@ -265,7 +286,11 @@ export class MultipleInputWidgetComponent extends PageComponent implements OnIni
switch (key.settings.dataKeyValueType) {
case 'dateTime':
case 'date':
value = _moment(keyData[0][1]).toDate();
if (isDefinedAndNotNull(keyData[0][1]) && keyData[0][1] !== '') {
value = _moment(keyData[0][1]).toDate();
} else {
value = null;
}
break;
case 'time':
value = _moment().startOf('day').add(keyData[0][1], 'ms').toDate();
@ -455,7 +480,7 @@ export class MultipleInputWidgetComponent extends PageComponent implements OnIni
if (tasks.length) {
forkJoin(tasks).subscribe(
() => {
this.multipleInputFormGroup.reset(undefined, {emitEvent: false});
// this.multipleInputFormGroup.reset(undefined, {emitEvent: false});
this.multipleInputFormGroup.markAsPristine();
if (this.settings.showResultMessage) {
this.ctx.showSuccessToast(this.translate.instant('widgets.input-widgets.update-successful'),
@ -469,7 +494,7 @@ export class MultipleInputWidgetComponent extends PageComponent implements OnIni
}
});
} else {
this.multipleInputFormGroup.reset(undefined, {emitEvent: false});
// this.multipleInputFormGroup.reset(undefined, {emitEvent: false});
this.multipleInputFormGroup.markAsPristine();
}
}

3
ui-ngx/src/assets/locale/locale.constant-en_US.json

@ -1991,8 +1991,11 @@
"entity-coordinate-required": "Both fields, latitude and longitude, are required",
"entity-timeseries-required": "Entity timeseries is required",
"get-location": "Get current location",
"invalid-date": "Invalid Date",
"latitude": "Latitude",
"longitude": "Longitude",
"min-value-error": "Min value is {{value}}",
"max-value-error": "Max value is {{value}}",
"not-allowed-entity": "Selected entity cannot have shared attributes",
"no-attribute-selected": "No attribute is selected",
"no-datakey-selected": "No datakey is selected",

Loading…
Cancel
Save