From: YuanHu Date: Tue, 27 Mar 2018 08:11:02 +0000 (+0800) Subject: Add shared/input. X-Git-Tag: v1.1.0~31 X-Git-Url: https://gerrit.onap.org/r/gitweb?a=commitdiff_plain;h=4c9bf1faeb4a143e3e2e0530a4abe2b7da8a64b6;p=sdc%2Fsdc-workflow-designer.git Add shared/input. Add shared/input. Issue-ID: SDC-1130,SDC-1131 Change-Id: Ib904ee1cf1801c094a04284d01062f9aecc9735e Signed-off-by: YuanHu --- diff --git a/sdc-workflow-designer-ui/src/app/shared/input/validators.ts b/sdc-workflow-designer-ui/src/app/shared/input/validators.ts new file mode 100644 index 00000000..6a4e799d --- /dev/null +++ b/sdc-workflow-designer-ui/src/app/shared/input/validators.ts @@ -0,0 +1,147 @@ +import {AbstractControl, ValidationErrors} from '@angular/forms'; + +export function inRangeValidator(in_range: number[]): ValidationErrors|null { + return (control: AbstractControl): ValidationErrors => { + const value = parseFloat(control.value); + if (isNaN(value) || value > in_range[1] || value < in_range[0]) { + control.setErrors({ + in_range: true + }); + return { + in_range: true + } + } else { + return null; + } + } +} + +export function greaterOrEqualValidator(max: string): ValidationErrors|null { + return (control: AbstractControl): ValidationErrors => { + const value = parseFloat(control.value); + const maxValue: any = parseFloat(max); + if (!isNaN(maxValue) && (isNaN(value) || value < maxValue)) { + control.setErrors({ + greater_or_equal: true + }); + return { + greater_or_equal: true + } + } else { + return null; + } + } +} + +export function lessOrEqualValidator(min: string): ValidationErrors|null { + return (control: AbstractControl): ValidationErrors => { + const value = parseFloat(control.value); + const minValue: any = parseFloat(min); + if (!isNaN(minValue) && (isNaN(value) || value > minValue)) { + control.setErrors({ + less_or_equal: true + }); + return { + less_or_equal: true + } + } else { + return null; + } + } +} + +export function greaterThanValidator(max: string): ValidationErrors|null { + return (control: AbstractControl): ValidationErrors => { + const value = parseFloat(control.value); + const maxValue: any = parseFloat(max); + if (!isNaN(maxValue) && (isNaN(value) || value <= maxValue)) { + control.setErrors({ + greater_than: true + }); + return { + greater_than: true + } + } else { + return null; + } + } +} + +export function lessThanValidator(min: string): ValidationErrors|null { + return (control: AbstractControl): ValidationErrors => { + const value = parseFloat(control.value); + const minValue: any = parseFloat(min); + if (!isNaN(minValue) && (isNaN(value) || value >= minValue)) { + control.setErrors({ + less_than: true + }); + return { + less_than: true + } + } else { + return null; + } + } +} + +export function equalValidator(value: any): ValidationErrors|null { + return (control: AbstractControl): ValidationErrors => { + if (control.value != value) { + control.setErrors({ + equal: true + }); + return { + equal: true + } + } else { + return null; + } + } +} + +export function lengthValidator(length: number): ValidationErrors|null { + return (control: AbstractControl): ValidationErrors => { + if (control.value && control.value.length !== length) { + control.setErrors({ + length: true + }); + return { + length: true + } + } else { + return null; + } + } +} + +export function floatValidator(): ValidationErrors|null { + return (control: AbstractControl): ValidationErrors => { + let floatPattern = /^(-?\d+)(\.\d+)?$/; + if (control.value && !floatPattern.test(control.value)) { + control.setErrors({ + float: true + }); + return { + float: true + } + } else { + return null; + } + } +} + +export function integerValidator(): ValidationErrors|null { + return (control: AbstractControl): ValidationErrors => { + let integerPattern = /^-?\d+$/; + if (control.value && !integerPattern.test(control.value)) { + control.setErrors({ + integer: true + }); + return { + integer: true + } + } else { + return null; + } + } +} \ No newline at end of file diff --git a/sdc-workflow-designer-ui/src/app/shared/input/wfm-text-input.component.ts b/sdc-workflow-designer-ui/src/app/shared/input/wfm-text-input.component.ts new file mode 100644 index 00000000..3b3798c7 --- /dev/null +++ b/sdc-workflow-designer-ui/src/app/shared/input/wfm-text-input.component.ts @@ -0,0 +1,258 @@ +import { + Component, Input, forwardRef, SimpleChanges, ViewChild, OnChanges, Output, EventEmitter, + ElementRef +} from '@angular/core'; +import {TranslateService} from '@ngx-translate/core'; +import { + ControlValueAccessor, NG_VALUE_ACCESSOR, NG_VALIDATORS, Validator, + AbstractControl, ValidationErrors +} from '@angular/forms'; +import { + inRangeValidator, greaterOrEqualValidator, lessOrEqualValidator, + greaterThanValidator, lessThanValidator, equalValidator, lengthValidator, floatValidator, integerValidator +} from './validators'; +import {isNullOrUndefined} from "util"; + +const noop = () => { +}; + +export const CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR: any = { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => WfmTextInputComponent), + multi: true +}; + +export const CUSTOM_INPUT_VALIDATOR: any = { + provide: NG_VALIDATORS, + useExisting: forwardRef(() => WfmTextInputComponent), + multi: true +}; + +@Component({ + selector: 'wfm-text-input', + template: ` + + + {{hintLabel}} + + {{ 'VALIDATE.REQUIRED' | translate }} + + + {{ 'VALIDATE.MAX_LENGTH' | translate: {value: maxlength} }} + + + {{ 'VALIDATE.MIN_LENGTH' | translate: {value: minlength} }} + + + {{ 'VALIDATE.LENGTH' | translate: {value: length} }} + + + {{ patternError }} + + + {{ getCommonRuleMessage(minlength + '-' + maxlength) }} + + + {{ 'VALIDATE.GREATER_OR_EQUAL' | translate: {value: greater_or_equal} }} + + + {{ 'VALIDATE.LESS_OR_EQUAL' | translate: {value: less_or_equal} }} + + + {{ 'VALIDATE.GREATER_THAN' | translate: {value: greater_than} }} + + + {{ 'VALIDATE.LESS_THAN' | translate: {value: less_than} }} + + + {{ 'VALIDATE.IN_RANGE' | translate: {value: in_range} }} + + + {{ 'VALIDATE.EQUAL' | translate: {value: equal} }} + + + {{ 'VALIDATE.FLOAT' | translate }} + + + {{ 'VALIDATE.INTEGER' | translate }} + + `, + styles: [` + .hint-label { + color:#7c868d; + } + input.ng-invalid { + border-color: #d9534f; + } + `], + providers: [CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR, CUSTOM_INPUT_VALIDATOR] +}) +export class WfmTextInputComponent implements ControlValueAccessor, Validator, OnChanges { + @Input() public disabled: boolean; + @Input() public inputType = 'string'; + @Input() public inputClass = 'form-control'; + @Input() public placeholder = ''; + @Input() public hintLabel: string; + @Input() public patternError: string; + @Input() public required = false; + @Input() public maxlength: number; + @Input() public minlength: number; + @Input() public pattern = ''; + @Input() public greater_or_equal: string; // >= + @Input() public less_or_equal: string; // <= + @Input() public greater_than: string; // > + @Input() public less_than: string; // < + @Input() public length: number; + @Input() public equal: any; + @Input() public in_range: string; + @Input() public isFocus: boolean; + @Output() public blur: any = new EventEmitter(); + @Output() public click: any = new EventEmitter(); + @ViewChild('wfInput') public wfInput: any; + + public isHintLabelShow = false; + private innerValue: any = ''; + private onTouchedCallback: () => void = noop; + private onChangeCallback: (_: any) => void = noop; + private _validators: any = {}; + public generalRules = '^(?![-_.])(?!\\d*$)[\\da-zA-Z-_.]*$'; + + constructor(public translate: TranslateService, + private elementRef: ElementRef) { + + } + + public ngOnChanges(changes: SimpleChanges): void { + this._createValidator(changes); + if (this.isFocus) { + this.elementRef.nativeElement.querySelector('input').focus(); + } + } + + // 动态创建Validator + private _createValidator(changes: SimpleChanges): void { + for (let change in changes) { + switch (change) { + case 'in_range': + if (!isNullOrUndefined(this.in_range)) { + this._validators.in_range = inRangeValidator(JSON.parse(this.in_range)); + } + break; + case 'greater_or_equal': + if (!isNullOrUndefined(this.greater_or_equal)) { + this._validators.greater_or_equal = greaterOrEqualValidator(this.greater_or_equal); + } + break; + case 'less_or_equal': + if (!isNullOrUndefined(this.less_or_equal)) { + this._validators.less_or_equal = lessOrEqualValidator(this.less_or_equal); + } + break; + case 'greater_than': + if (!isNullOrUndefined(this.greater_than)) { + this._validators.greater_than = greaterThanValidator(this.greater_than); + } + break; + case 'less_than': + if (!isNullOrUndefined(this.less_than)) { + this._validators.less_than = lessThanValidator(this.less_than); + } + break; + case 'equal': + if (!isNullOrUndefined(this.equal)) { + this._validators.equal = equalValidator(this.equal); + } + break; + case 'length': + if (!isNullOrUndefined(this.length)) { + this._validators.length = lengthValidator(this.length); + } + break; + case 'inputType': + delete this._validators.float; + delete this._validators.integer; + if (this.inputType === 'float') { + this._validators.float = floatValidator(); + } else if (this.inputType === 'integer') { + this._validators.integer = integerValidator(); + } + break; + } + } + } + + // 执行控件验证 + public validate(c: AbstractControl): ValidationErrors | null { + let errors: any; + for (let validatorName in this._validators) { + let validator = this._validators[validatorName]; + if (validator) { + let errors = validator(c); + if (errors) { + return errors; + } + } + } + return null; + } + + public onFocus(): void { + if (this.isFocus) { + this.click.emit(); + } + this.isHintLabelShow = true; + } + + public onBlur(): void { + this.blur.emit(); + this.isHintLabelShow = false; + this.onTouchedCallback(); + } + + get value(): any { + this.validate(this.wfInput.control); + return this.innerValue; + }; + + set value(value: any) { + if (value !== this.innerValue) { + this.innerValue = value; + this.onChangeCallback(value); + } + } + + writeValue(value: any) { + if (value !== this.innerValue) { + this.innerValue = value; + } + } + + registerOnChange(fn: any) { + this.onChangeCallback = fn; + } + + registerOnTouched(fn: any) { + this.onTouchedCallback = fn; + } + + public getCommonRuleMessage(length: any): string { + let message = this.translate.get('VALIDATE.FIRST_CHARACTER')['value'] + ', ' + + this.translate.get('VALIDATE.NOT_ALL_NUMBER')['value'] + ', ' + + this.translate.get('VALIDATE.CHARACTER_LIMIT', {value: '[0-9],[a-z],[A-Z],[_],[-],[.]'})['value'] + ', ' + + this.translate.get('VALIDATE.CHARACTER_LENGTH', {value: length})['value']; + return message; + } +} diff --git a/sdc-workflow-designer-ui/src/app/shared/input/wfm-text-input.module.ts b/sdc-workflow-designer-ui/src/app/shared/input/wfm-text-input.module.ts new file mode 100644 index 00000000..8dbfd47f --- /dev/null +++ b/sdc-workflow-designer-ui/src/app/shared/input/wfm-text-input.module.ts @@ -0,0 +1,15 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { TranslateModule } from '@ngx-translate/core'; +import { FormsModule } from '@angular/forms'; +import { WfmTextInputComponent } from './wfm-text-input.component'; + +@NgModule({ + imports: [TranslateModule, CommonModule, FormsModule], + declarations: [WfmTextInputComponent], + exports: [WfmTextInputComponent] +}) + +export class WfmInputModule { + +} \ No newline at end of file