Add shared/input. 49/38949/3
authorYuanHu <yuan.hu1@zte.com.cn>
Tue, 27 Mar 2018 08:11:02 +0000 (16:11 +0800)
committerYuanHu <yuan.hu1@zte.com.cn>
Tue, 27 Mar 2018 08:48:11 +0000 (16:48 +0800)
Add shared/input.

Issue-ID: SDC-1130,SDC-1131

Change-Id: Ib904ee1cf1801c094a04284d01062f9aecc9735e
Signed-off-by: YuanHu <yuan.hu1@zte.com.cn>
sdc-workflow-designer-ui/src/app/shared/input/validators.ts [new file with mode: 0644]
sdc-workflow-designer-ui/src/app/shared/input/wfm-text-input.component.ts [new file with mode: 0644]
sdc-workflow-designer-ui/src/app/shared/input/wfm-text-input.module.ts [new file with mode: 0644]

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 (file)
index 0000000..6a4e799
--- /dev/null
@@ -0,0 +1,147 @@
+import {AbstractControl, ValidationErrors} from '@angular/forms';\r
+\r
+export function inRangeValidator(in_range: number[]): ValidationErrors|null {\r
+    return (control: AbstractControl): ValidationErrors => {\r
+        const value = parseFloat(control.value);\r
+        if (isNaN(value) || value > in_range[1] || value < in_range[0]) {\r
+            control.setErrors({\r
+                in_range: true\r
+            });\r
+            return {\r
+                in_range: true\r
+            }\r
+        } else {\r
+            return null;\r
+        }\r
+    }\r
+}\r
+\r
+export function greaterOrEqualValidator(max: string): ValidationErrors|null {\r
+    return (control: AbstractControl): ValidationErrors => {\r
+        const value = parseFloat(control.value);\r
+        const maxValue: any = parseFloat(max);\r
+        if (!isNaN(maxValue) && (isNaN(value) || value < maxValue)) {\r
+            control.setErrors({\r
+                greater_or_equal: true\r
+            });\r
+            return {\r
+                greater_or_equal: true\r
+            }\r
+        } else {\r
+            return null;\r
+        }\r
+    }\r
+}\r
+\r
+export function lessOrEqualValidator(min: string): ValidationErrors|null {\r
+    return (control: AbstractControl): ValidationErrors => {\r
+        const value = parseFloat(control.value);\r
+        const minValue: any = parseFloat(min);\r
+        if (!isNaN(minValue) && (isNaN(value) || value > minValue)) {\r
+            control.setErrors({\r
+                less_or_equal: true\r
+            });\r
+            return {\r
+                less_or_equal: true\r
+            }\r
+        } else {\r
+            return null;\r
+        }\r
+    }\r
+}\r
+\r
+export function greaterThanValidator(max: string): ValidationErrors|null {\r
+    return (control: AbstractControl): ValidationErrors => {\r
+        const value = parseFloat(control.value);\r
+        const maxValue: any = parseFloat(max);\r
+        if (!isNaN(maxValue) && (isNaN(value) || value <= maxValue)) {\r
+            control.setErrors({\r
+                greater_than: true\r
+            });\r
+            return {\r
+                greater_than: true\r
+            }\r
+        } else {\r
+            return null;\r
+        }\r
+    }\r
+}\r
+\r
+export function lessThanValidator(min: string): ValidationErrors|null {\r
+    return (control: AbstractControl): ValidationErrors => {\r
+        const value = parseFloat(control.value);\r
+        const minValue: any = parseFloat(min);\r
+        if (!isNaN(minValue) && (isNaN(value) || value >= minValue)) {\r
+            control.setErrors({\r
+                less_than: true\r
+            });\r
+            return {\r
+                less_than: true\r
+            }\r
+        } else {\r
+            return null;\r
+        }\r
+    }\r
+}\r
+\r
+export function equalValidator(value: any): ValidationErrors|null {\r
+    return (control: AbstractControl): ValidationErrors => {\r
+        if (control.value != value) {\r
+            control.setErrors({\r
+                equal: true\r
+            });\r
+            return {\r
+                equal: true\r
+            }\r
+        } else {\r
+            return null;\r
+        }\r
+    }\r
+}\r
+\r
+export function lengthValidator(length: number): ValidationErrors|null {\r
+    return (control: AbstractControl): ValidationErrors => {\r
+        if (control.value && control.value.length !== length) {\r
+            control.setErrors({\r
+                length: true\r
+            });\r
+            return {\r
+                length: true\r
+            }\r
+        } else {\r
+            return null;\r
+        }\r
+    }\r
+}\r
+\r
+export function floatValidator(): ValidationErrors|null {\r
+    return (control: AbstractControl): ValidationErrors => {\r
+        let floatPattern = /^(-?\d+)(\.\d+)?$/;\r
+        if (control.value && !floatPattern.test(control.value)) {\r
+            control.setErrors({\r
+                float: true\r
+            });\r
+            return {\r
+                float: true\r
+            }\r
+        } else {\r
+            return null;\r
+        }\r
+    }\r
+}\r
+\r
+export function integerValidator(): ValidationErrors|null {\r
+    return (control: AbstractControl): ValidationErrors => {\r
+        let integerPattern = /^-?\d+$/;\r
+        if (control.value && !integerPattern.test(control.value)) {\r
+            control.setErrors({\r
+                integer: true\r
+            });\r
+            return {\r
+                integer: true\r
+            }\r
+        } else {\r
+            return null;\r
+        }\r
+    }\r
+}
\ 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 (file)
index 0000000..3b3798c
--- /dev/null
@@ -0,0 +1,258 @@
+import {\r
+    Component, Input, forwardRef, SimpleChanges, ViewChild, OnChanges, Output, EventEmitter,\r
+    ElementRef\r
+} from '@angular/core';\r
+import {TranslateService} from '@ngx-translate/core';\r
+import {\r
+    ControlValueAccessor, NG_VALUE_ACCESSOR, NG_VALIDATORS, Validator,\r
+    AbstractControl, ValidationErrors\r
+} from '@angular/forms';\r
+import {\r
+    inRangeValidator, greaterOrEqualValidator, lessOrEqualValidator,\r
+    greaterThanValidator, lessThanValidator, equalValidator, lengthValidator, floatValidator, integerValidator\r
+} from './validators';\r
+import {isNullOrUndefined} from "util";\r
+\r
+const noop = () => {\r
+};\r
+\r
+export const CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR: any = {\r
+    provide: NG_VALUE_ACCESSOR,\r
+    useExisting: forwardRef(() => WfmTextInputComponent),\r
+    multi: true\r
+};\r
+\r
+export const CUSTOM_INPUT_VALIDATOR: any = {\r
+    provide: NG_VALIDATORS,\r
+    useExisting: forwardRef(() => WfmTextInputComponent),\r
+    multi: true\r
+};\r
+\r
+@Component({\r
+    selector: 'wfm-text-input',\r
+    template: `\r
+        <input type="text"\r
+            [disabled]="disabled" \r
+            [class]="inputClass"\r
+            [placeholder]="placeholder"\r
+            [required]="required"\r
+            [maxlength]="maxlength"\r
+            [minlength]="minlength"\r
+            [pattern]="pattern"\r
+            (focus)="onFocus()"\r
+            (blur)="onBlur()"\r
+            [(ngModel)]="value"\r
+            [ngModelOptions]="{standalone: true}"\r
+            #wfInput="ngModel"\r
+        />\r
+\r
+        <small [hidden]="!wfInput.valid || !hintLabel || !isHintLabelShow" class="hint-label">{{hintLabel}}</small>\r
+        <small [hidden]="!wfInput.errors?.required" class="text-danger">\r
+            {{ 'VALIDATE.REQUIRED' | translate }}\r
+        </small>\r
+        <small [hidden]="!wfInput.errors?.maxlength" class="text-danger">\r
+            {{ 'VALIDATE.MAX_LENGTH' | translate: {value: maxlength} }}\r
+        </small>\r
+        <small [hidden]="!wfInput.errors?.minlength" class="text-danger">\r
+            {{ 'VALIDATE.MIN_LENGTH' | translate: {value: minlength} }}\r
+        </small>\r
+        <small [hidden]="!wfInput.errors?.length" class="text-danger">\r
+            {{ 'VALIDATE.LENGTH' | translate: {value: length} }}\r
+        </small>\r
+        <small *ngIf="patternError" [hidden]="!wfInput.errors?.pattern" class="text-danger">\r
+            {{ patternError }}\r
+        </small>\r
+        <small *ngIf="!patternError && pattern === generalRules" [hidden]="!wfInput.errors?.pattern" class="text-danger">\r
+            {{ getCommonRuleMessage(minlength + '-' + maxlength) }}\r
+        </small>\r
+        <small [hidden]="!wfInput.errors?.greater_or_equal" class="text-danger">\r
+            {{ 'VALIDATE.GREATER_OR_EQUAL' | translate: {value: greater_or_equal} }}\r
+        </small>\r
+        <small [hidden]="!wfInput.errors?.less_or_equal" class="text-danger">\r
+            {{ 'VALIDATE.LESS_OR_EQUAL' | translate: {value: less_or_equal} }}\r
+        </small>\r
+        <small [hidden]="!wfInput.errors?.greater_than" class="text-danger">\r
+            {{ 'VALIDATE.GREATER_THAN' | translate: {value: greater_than} }}\r
+        </small>\r
+        <small [hidden]="!wfInput.errors?.less_than" class="text-danger">\r
+            {{ 'VALIDATE.LESS_THAN' | translate: {value: less_than} }}\r
+        </small>\r
+        <small [hidden]="!wfInput.errors?.in_range" class="text-danger">\r
+            {{ 'VALIDATE.IN_RANGE' | translate: {value: in_range} }}\r
+        </small>\r
+        <small [hidden]="!wfInput.errors?.equal" class="text-danger">\r
+            {{ 'VALIDATE.EQUAL' | translate: {value: equal} }}\r
+        </small>\r
+        <small [hidden]="!wfInput.errors?.float" class="text-danger">\r
+            {{ 'VALIDATE.FLOAT' | translate }}\r
+        </small>\r
+        <small [hidden]="!wfInput.errors?.integer" class="text-danger">\r
+            {{ 'VALIDATE.INTEGER' | translate }}\r
+        </small>\r
+    `,\r
+    styles: [`\r
+        .hint-label {\r
+            color:#7c868d;\r
+        }\r
+        input.ng-invalid {\r
+            border-color: #d9534f;\r
+        }\r
+    `],\r
+    providers: [CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR, CUSTOM_INPUT_VALIDATOR]\r
+})\r
+export class WfmTextInputComponent implements ControlValueAccessor, Validator, OnChanges {\r
+    @Input() public disabled: boolean;\r
+    @Input() public inputType = 'string';\r
+    @Input() public inputClass = 'form-control';\r
+    @Input() public placeholder = '';\r
+    @Input() public hintLabel: string;\r
+    @Input() public patternError: string;\r
+    @Input() public required = false;\r
+    @Input() public maxlength: number;\r
+    @Input() public minlength: number;\r
+    @Input() public pattern = '';\r
+    @Input() public greater_or_equal: string; // >=\r
+    @Input() public less_or_equal: string;    // <=\r
+    @Input() public greater_than: string;     // >\r
+    @Input() public less_than: string;        // <\r
+    @Input() public length: number;\r
+    @Input() public equal: any;\r
+    @Input() public in_range: string;\r
+    @Input() public isFocus: boolean;\r
+    @Output() public blur: any = new EventEmitter();\r
+    @Output() public click: any = new EventEmitter();\r
+    @ViewChild('wfInput') public wfInput: any;\r
+\r
+    public isHintLabelShow = false;\r
+    private innerValue: any = '';\r
+    private onTouchedCallback: () => void = noop;\r
+    private onChangeCallback: (_: any) => void = noop;\r
+    private _validators: any = {};\r
+    public generalRules = '^(?![-_.])(?!\\d*$)[\\da-zA-Z-_.]*$';\r
+\r
+    constructor(public translate: TranslateService,\r
+                private elementRef: ElementRef) {\r
+\r
+    }\r
+\r
+    public ngOnChanges(changes: SimpleChanges): void {\r
+        this._createValidator(changes);\r
+        if (this.isFocus) {\r
+            this.elementRef.nativeElement.querySelector('input').focus();\r
+        }\r
+    }\r
+\r
+    // 动态创建Validator\r
+    private _createValidator(changes: SimpleChanges): void {\r
+        for (let change in changes) {\r
+            switch (change) {\r
+                case 'in_range':\r
+                    if (!isNullOrUndefined(this.in_range)) {\r
+                        this._validators.in_range = inRangeValidator(JSON.parse(this.in_range));\r
+                    }\r
+                    break;\r
+                case 'greater_or_equal':\r
+                    if (!isNullOrUndefined(this.greater_or_equal)) {\r
+                        this._validators.greater_or_equal = greaterOrEqualValidator(this.greater_or_equal);\r
+                    }\r
+                    break;\r
+                case 'less_or_equal':\r
+                    if (!isNullOrUndefined(this.less_or_equal)) {\r
+                        this._validators.less_or_equal = lessOrEqualValidator(this.less_or_equal);\r
+                    }\r
+                    break;\r
+                case 'greater_than':\r
+                    if (!isNullOrUndefined(this.greater_than)) {\r
+                        this._validators.greater_than = greaterThanValidator(this.greater_than);\r
+                    }\r
+                    break;\r
+                case 'less_than':\r
+                    if (!isNullOrUndefined(this.less_than)) {\r
+                        this._validators.less_than = lessThanValidator(this.less_than);\r
+                    }\r
+                    break;\r
+                case 'equal':\r
+                    if (!isNullOrUndefined(this.equal)) {\r
+                        this._validators.equal = equalValidator(this.equal);\r
+                    }\r
+                    break;\r
+                case 'length':\r
+                    if (!isNullOrUndefined(this.length)) {\r
+                        this._validators.length = lengthValidator(this.length);\r
+                    }\r
+                    break;\r
+                case 'inputType':\r
+                    delete this._validators.float;\r
+                    delete this._validators.integer;\r
+                    if (this.inputType === 'float') {\r
+                        this._validators.float = floatValidator();\r
+                    } else if (this.inputType === 'integer') {\r
+                        this._validators.integer = integerValidator();\r
+                    }\r
+                    break;\r
+            }\r
+        }\r
+    }\r
+\r
+    // 执行控件验证\r
+    public validate(c: AbstractControl): ValidationErrors | null {\r
+        let errors: any;\r
+        for (let validatorName in this._validators) {\r
+            let validator = this._validators[validatorName];\r
+            if (validator) {\r
+                let errors = validator(c);\r
+                if (errors) {\r
+                    return errors;\r
+                }\r
+            }\r
+        }\r
+        return null;\r
+    }\r
+\r
+    public onFocus(): void {\r
+        if (this.isFocus) {\r
+            this.click.emit();\r
+        }\r
+        this.isHintLabelShow = true;\r
+    }\r
+\r
+    public onBlur(): void {\r
+        this.blur.emit();\r
+        this.isHintLabelShow = false;\r
+        this.onTouchedCallback();\r
+    }\r
+\r
+    get value(): any {\r
+        this.validate(this.wfInput.control);\r
+        return this.innerValue;\r
+    };\r
+\r
+    set value(value: any) {\r
+        if (value !== this.innerValue) {\r
+            this.innerValue = value;\r
+            this.onChangeCallback(value);\r
+        }\r
+    }\r
+\r
+    writeValue(value: any) {\r
+        if (value !== this.innerValue) {\r
+            this.innerValue = value;\r
+        }\r
+    }\r
+\r
+    registerOnChange(fn: any) {\r
+        this.onChangeCallback = fn;\r
+    }\r
+\r
+    registerOnTouched(fn: any) {\r
+        this.onTouchedCallback = fn;\r
+    }\r
+\r
+    public getCommonRuleMessage(length: any): string {\r
+        let message = this.translate.get('VALIDATE.FIRST_CHARACTER')['value'] + ', ' +\r
+            this.translate.get('VALIDATE.NOT_ALL_NUMBER')['value'] + ', ' +\r
+            this.translate.get('VALIDATE.CHARACTER_LIMIT', {value: '[0-9],[a-z],[A-Z],[_],[-],[.]'})['value'] + ', ' +\r
+            this.translate.get('VALIDATE.CHARACTER_LENGTH', {value: length})['value'];\r
+        return message;\r
+    }\r
+}\r
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 (file)
index 0000000..8dbfd47
--- /dev/null
@@ -0,0 +1,15 @@
+import { NgModule } from '@angular/core';\r
+import { CommonModule } from '@angular/common';\r
+import { TranslateModule } from '@ngx-translate/core';\r
+import { FormsModule } from '@angular/forms';\r
+import { WfmTextInputComponent } from './wfm-text-input.component';\r
+\r
+@NgModule({\r
+    imports: [TranslateModule, CommonModule, FormsModule],\r
+    declarations: [WfmTextInputComponent],\r
+    exports: [WfmTextInputComponent]\r
+})\r
+\r
+export class WfmInputModule {\r
+\r
+}
\ No newline at end of file