UNPKG

ngx-validator

Version:

It is an angular library which has custom input and validation component, custom validation directive and form template generator, which work on data based on typesript class property decorators. Custom validation directive replaces html input validator

903 lines (890 loc) 63.8 kB
import * as i0 from '@angular/core'; import { Injectable, Directive, Input, Component, HostBinding, ViewChild, ContentChildren, EventEmitter, forwardRef, Output, HostListener, NgModule } from '@angular/core'; import * as i2 from '@angular/forms'; import { NgControl, NG_VALUE_ACCESSOR, NG_VALIDATORS, NgModel, FormControlName, NgForm, FormsModule, ReactiveFormsModule } from '@angular/forms'; import 'reflect-metadata'; import * as i1 from '@angular/common'; import { CommonModule } from '@angular/common'; import * as i2$1 from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core'; class NgxValidatorService { constructor() { } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.3", ngImport: i0, type: NgxValidatorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.3", ngImport: i0, type: NgxValidatorService, providedIn: 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.3", ngImport: i0, type: NgxValidatorService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: () => [] }); var DataTypeEnum; (function (DataTypeEnum) { DataTypeEnum[DataTypeEnum["Int"] = 0] = "Int"; DataTypeEnum[DataTypeEnum["Number"] = 1] = "Number"; DataTypeEnum[DataTypeEnum["MultilineText"] = 2] = "MultilineText"; DataTypeEnum[DataTypeEnum["Url"] = 3] = "Url"; DataTypeEnum[DataTypeEnum["ImageUrl"] = 4] = "ImageUrl"; DataTypeEnum[DataTypeEnum["Password"] = 5] = "Password"; DataTypeEnum[DataTypeEnum["Hexadecimal"] = 6] = "Hexadecimal"; DataTypeEnum[DataTypeEnum["Date"] = 7] = "Date"; DataTypeEnum[DataTypeEnum["Array"] = 8] = "Array"; DataTypeEnum[DataTypeEnum["Upload"] = 9] = "Upload"; })(DataTypeEnum || (DataTypeEnum = {})); function isEmpty(obj) { for (const key in obj) { if (obj.hasOwnProperty(key)) { return false; } } return true; } // tslint:disable-next-line:callable-types function ModelState(constructor) { return class extends constructor { /** * Returns model validation state */ IsValid() { for (const item of Reflect.getMetadataKeys(this)) { const attribs = getDecorators(this, item); for (const attrib of attribs.filter(x => x.key !== 'ReadOnly' && x.key !== 'NoForm')) { const messg = ngxValidate(attrib.key, attrib.value, this[item], this); if (messg) { return false; } } } return true; } /** * Placeholder(string) * Validate: function */ ModelErrors() { const errs = {}; let tmp = {}; for (const item of Reflect.getMetadataKeys(this)) { const attribs = getDecorators(this, item); for (const attrib of attribs.filter(x => x.key !== 'ReadOnly' && x.key !== 'NoForm')) { const messg = ngxValidate(attrib.key, attrib.value, this[item], this); if (messg) { tmp[attrib.key] = messg; } } if (!isEmpty(tmp)) { errs[item] = tmp; } tmp = {}; } return errs; } }; } /** * Validates field if it has valid value according to value parameter */ function DataType(param) { return (target, propertyKey) => { Reflect.defineMetadata(propertyKey, param, target); Reflect.defineMetadata('custom-reflect:DataType', param, target, propertyKey); }; } /** * Validates field if it represents valid credit card number */ function CreditCard(param) { return (target, propertyKey) => { Reflect.defineMetadata(propertyKey, param, target); Reflect.defineMetadata('custom-reflect:CreditCard', param, target, propertyKey); }; } /** * Compares field to other field and checks if they are equal */ function Compare(param) { return (target, propertyKey) => { Reflect.defineMetadata(propertyKey, param, target); Reflect.defineMetadata('custom-reflect:Compare', param, target, propertyKey); }; } /** * Validates if field value contains specific value */ function Contains(param) { return (target, propertyKey) => { Reflect.defineMetadata(propertyKey, param, target); Reflect.defineMetadata('custom-reflect:Contains', param, target, propertyKey); }; } /** * Validates field according to custom logic */ function Custom(param) { return (target, propertyKey) => { Reflect.defineMetadata(propertyKey, param, target); Reflect.defineMetadata('custom-reflect:Custom', param, target, propertyKey); }; } /** * Sets the name metadata for the field */ function Name(param) { return (target, propertyKey) => { Reflect.defineMetadata(propertyKey, param, target); Reflect.defineMetadata('custom-reflect:Name', param, target, propertyKey); }; } /** * Validates field and checks if it has null, undefined or empty value */ function Required(param) { return (target, propertyKey) => { Reflect.defineMetadata(propertyKey, param, target); Reflect.defineMetadata('custom-reflect:Required', param, target, propertyKey); }; } /** * Validates field if other field has specific value and checks if it has null, undefined or empty value */ function RequiredIf(param) { return (target, propertyKey) => { Reflect.defineMetadata(propertyKey, param, target); Reflect.defineMetadata('custom-reflect:RequiredIf', param, target, propertyKey); }; } /** * Sets field's input value to readonly */ function ReadOnly() { return (target, propertyKey) => { Reflect.defineMetadata(propertyKey, propertyKey, target); Reflect.defineMetadata('custom-reflect:ReadOnly', null, target, propertyKey); }; } /** * Validates if field has valid value according to specified pattern */ function Pattern(param) { return (target, propertyKey) => { Reflect.defineMetadata(propertyKey, param, target); Reflect.defineMetadata('custom-reflect:Pattern', param, target, propertyKey); }; } /** * Validates if field has valid value more than specific value */ function MinValue(input) { return (target, propertyKey) => { Reflect.defineMetadata(propertyKey, input, target); Reflect.defineMetadata('custom-reflect:MinValue', input, target, propertyKey); }; } /** * Validates if field has valid value less than specific value */ function MaxValue(input) { return (target, propertyKey) => { Reflect.defineMetadata(propertyKey, input, target); Reflect.defineMetadata('custom-reflect:MaxValue', input, target, propertyKey); }; } /** * Validates if field value does not contain specific value */ function NotContains(param) { return (target, propertyKey) => { Reflect.defineMetadata(propertyKey, param, target); Reflect.defineMetadata('custom-reflect:NotContains', param, target, propertyKey); }; } /** * Tells form generator component not to generate input for this field */ function NoForm() { return (target, propertyKey) => { Reflect.defineMetadata(propertyKey, propertyKey, target); Reflect.defineMetadata('custom-reflect:NoForm', null, target, propertyKey); }; } /** * Validates if field value length fits in min and max values */ function StringLength(input) { return (target, propertyKey) => { Reflect.defineMetadata(propertyKey, input, target); Reflect.defineMetadata('custom-reflect:StringLength', input, target, propertyKey); }; } /** * Validates if field value is valid email value */ function Email(input) { return (target, propertyKey) => { Reflect.defineMetadata(propertyKey, input, target); Reflect.defineMetadata('custom-reflect:Email', input, target, propertyKey); }; } /** * Sets placeholder value for field input */ function Placeholder(input) { return (target, propertyKey) => { Reflect.defineMetadata(propertyKey, input, target); Reflect.defineMetadata('custom-reflect:Placeholder', input, target, propertyKey); }; } /** * Validates if field value length fits in min and max values */ function Range(input) { return (target, propertyKey) => { Reflect.defineMetadata(propertyKey, input, target); Reflect.defineMetadata('custom-reflect:Range', input, target, propertyKey); }; } function configurable(value) { return (target, propertyKey, descriptor) => { descriptor.configurable = value; }; } /** * Placeholder(string) * Validate: function */ function getDecorators(target, propertyName) { const keys = Reflect.getMetadataKeys(target, propertyName); const decorators = keys.filter(key => key.toString().startsWith('custom-reflect:')) .reduce((values, key) => { const value = Reflect.getMetadata(key, target, propertyName); return values.concat({ key: key.toString().replace('custom-reflect:', ''), value }); }, []); return decorators; } function ngxValidate(key, param, value, dataModel) { let retstr; if ((value === null || value === undefined || value === '') && key !== 'Required' && key !== 'RequiredIf' && key !== 'Compare' && key !== 'Range') { return null; } let errorString = ''; if (typeof param === 'string') { errorString = param; } else { errorString = param.error; } if (!errorString) { errorString = 'error not asigned!'; } switch (key) { case 'CreditCard': { value = value.replace(/[- ]+/g, ''); const Visa = /^4[0-9]{12}(?:[0-9]{3})?$/; const MasterCard = /^(?:5[1-5][0-9]{2}|222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}$/; const Amex = /^3[47][0-9]{13}$/; const DinersClub = /^3(?:0[0-5]|[68][0-9])[0-9]{11}$/; const Discover = /^6(?:011|5[0-9]{2})[0-9]{12}$/; const JCB = /^(?:2131|1800|35\d{3})\d{11}$/; const BCGlobal = /^(6541|6556)[0-9]{12}$/; const CarteBlanche = /^389[0-9]{11}$/; const InstaPayment = /^63[7-9][0-9]{13}$/; const KoreanLocalCard = /^9[0-9]{15}$/; const Laser = /^(6304|6706|6709|6771)[0-9]{12,15}$/; const Maestro = /^(5018|5020|5038|6304|6759|6761|6763)[0-9]{8,15}$/; const Solo = /^(6334|6767)[0-9]{12}|(6334|6767)[0-9]{14}|(6334|6767)[0-9]{15}$/; // tslint:disable-next-line:max-line-length const Switch = /^(4903|4905|4911|4936|6333|6759)[0-9]{12}|(4903|4905|4911|4936|6333|6759)[0-9]{14}|(4903|4905|4911|4936|6333|6759)[0-9]{15}|564182[0-9]{10}|564182[0-9]{12}|564182[0-9]{13}|633110[0-9]{10}|633110[0-9]{12}|633110[0-9]{13}$/; const UnionPay = /^(62[0-9]{14,17})$/; if (!checkLuhn(value) || !(Visa.test(value) || MasterCard.test(value) || Amex.test(value) || DinersClub.test(value) || Discover.test(value) || JCB.test(value) || BCGlobal.test(value) || CarteBlanche.test(value) || InstaPayment.test(value) || KoreanLocalCard.test(value) || Laser.test(value) || Maestro.test(value) || Solo.test(value) || Switch.test(value) || UnionPay.test(value) || (param.customValue && param.customValue.test(value)))) { retstr = param.error; } break; } case 'Compare': { if (value !== dataModel[param.field]) { retstr = errorString; } break; } case 'Contains': { if (value.indexOf(param.value) === -1) { retstr = errorString; } break; } case 'Custom': { const result = param.customFunc(value, dataModel); if (!result) { retstr = errorString; } break; } case 'DataType': { if (param.value === DataTypeEnum.Number) { const reg = /^[+-]?\d+(\.\d+)?$/; if (isNaN(parseFloat(value)) || !reg.test(value)) { retstr = errorString; } } if (param.value === DataTypeEnum.Date) { if (!(value instanceof Date)) { retstr = errorString; } } if (param.value === DataTypeEnum.Hexadecimal) { const expression = /^([0-9a-fA-F]+)$/i; if (!expression.test(value)) { retstr = errorString; } } if (param.value === DataTypeEnum.Int) { const reg = /^[+\-]?\d+$/; if (isNaN(parseFloat(value)) || !isNaN(parseFloat(value)) && (parseFloat(value) - parseInt(value, 10) !== 0) || !reg.test(value)) { retstr = errorString; } } if (param.value === DataTypeEnum.Array) { if (!Array.isArray(value)) { retstr = errorString; } } break; } case 'NotContains': { if (value.indexOf(param.value) !== -1) { retstr = errorString; } break; } case 'Required': { if (value === null || value === undefined || value === '') { retstr = errorString; } break; } case 'RequiredIf': { if (!param.field || !param.value) { console.warn('incorrect parameters in RequiredIf attribute'); } else { if ((param.value === dataModel[param.field]) && (value === null || value === undefined || value === '')) { retstr = errorString; } } break; } case 'Pattern': { const pat = param.value; if (!pat.test(value)) { retstr = errorString; } break; } case 'MinValue': { if (value < param.value) { retstr = errorString.replace('{0}', param.value.toString()); } break; } case 'MaxValue': { if (value > param.value) { retstr = errorString.replace('{0}', param.value.toString()); } break; } case 'StringLength': { if (!value || value.length < param.min || value.length > param.max) { retstr = errorString.replace('{0}', param.min .toString()) .replace('{1}', param.max.toString()); } break; } case 'Range': { if (value < param.min || value > param.max) { retstr = errorString.replace('{0}', param.min .toString()) .replace('{1}', param.max.toString()); } break; } case 'Email': { // credits http://emailregex.com/ // tslint:disable-next-line:max-line-length const emreg = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; if (!emreg.test(value)) { retstr = errorString; } break; } default: { retstr = null; break; } } return retstr; } function checkLuhn(value) { // credits https://github.com/JamesEggers1/node-luhn const trimmed = String(value).replace(/[\s]/g, ''); const length = trimmed.length; let odd = false; let total = 0; let calc; let calc2; if (length === 0) { return true; } if (!/^[0-9]+$/.test(trimmed)) { return false; } for (let i = length; i > 0; i--) { calc = parseInt(trimmed.charAt(i - 1), 10); if (!odd) { total += calc; } else { calc2 = calc * 2; switch (calc2) { case 10: calc2 = 1; break; case 12: calc2 = 3; break; case 14: calc2 = 5; break; case 16: calc2 = 7; break; case 18: calc2 = 9; break; default: calc2 = calc2; } total += calc2; } odd = !odd; } return (total !== 0 && (total % 10) === 0); } // credits to https://github.com/clbond/form-example class ValueAccessorBase { get formControl() { if (this.control != null) { return this.control; } this.control = this.theInjector.get(NgControl, null); return this.control; } get value() { return this.innerValue; } set value(value) { if (this.innerValue !== value) { this.innerValue = value; if (this.onChange) { this.onChange(value); } } } constructor(theInjector) { this.theInjector = theInjector; this.onChange = null; this.onTouch = null; } writeValue(value) { this.innerValue = value; if (this.onChange) { this.onChange(value); } } registerOnChange(fn) { this.onChange = fn; } registerOnTouched(fn) { this.onTouch = fn; } setDisabledState(disabled) { this.disabled = disabled; } touch() { if (this.onTouch) { this.onTouch(); } } } function validateControl(control, dataModel) { let name; if (control.parent) { for (const item of Object.keys(control.parent.controls)) { if (control.parent.controls[item] === control) { name = item; } } } else { name = this.field; } const attribs = getDecorators(dataModel, name); const errs = {}; if (attribs.find(x => x.key === 'ReadOnly')) { this.el.nativeElement.setAttribute('readonly', true); } for (const item of attribs.filter(x => x.key !== 'ReadOnly' && x.key !== 'NoForm')) { const messg = ngxValidate(item.key, item.value, control.value, dataModel); if (messg) { errs[item.key] = messg; } } return errs; } class ElementBase extends ValueAccessorBase { constructor(injector) { super(injector); this.injector = injector; this.validator = validateControl; } validate(control) { return this.validator(control, this.model); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.3", ngImport: i0, type: ElementBase, deps: [{ token: i0.Injector }], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.3", type: ElementBase, inputs: { model: "model" }, usesInheritance: true, ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.3", ngImport: i0, type: ElementBase, decorators: [{ type: Directive }], ctorParameters: () => [{ type: i0.Injector }], propDecorators: { model: [{ type: Input }] } }); class NgxCustomTemplateForDirective { constructor(templateRef, viewContainer) { this.templateRef = templateRef; this.viewContainer = viewContainer; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.3", ngImport: i0, type: NgxCustomTemplateForDirective, deps: [{ token: i0.TemplateRef }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.3", type: NgxCustomTemplateForDirective, selector: "[ngxCustomTemplateFor]", inputs: { ngxCustomTemplateFor: "ngxCustomTemplateFor" }, ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.3", ngImport: i0, type: NgxCustomTemplateForDirective, decorators: [{ type: Directive, args: [{ // tslint:disable-next-line:directive-selector selector: '[ngxCustomTemplateFor]' }] }], ctorParameters: () => [{ type: i0.TemplateRef }, { type: i0.ViewContainerRef }], propDecorators: { ngxCustomTemplateFor: [{ type: Input }] } }); class NgxDropdownForComponent extends ElementBase { set templates(value) { if (this.model) { value.forEach((item) => { this.template = item; }); } } constructor(el, injector) { super(injector); this.el = el; this.injector = injector; this.DataTypeEnum = DataTypeEnum; this.placeHolder = ''; this.name = ''; this.readonly = false; this.ngxDropdown = true; this.itemSource = []; this.valuePrimitive = true; this.defaultItem = true; } ngOnInit() { if (!this.model) { console.error('ngx-validator error! [model] property is not binded!'); } if (this.field === null || this.field === undefined) { this.field = this.el.nativeElement.getAttribute('name') === null ? this.el.nativeElement.getAttribute('id') : this.el.nativeElement.getAttribute('name'); } if (!this.field) { this.field = this.el.nativeElement.getAttribute('formControlName'); } const attribs = getDecorators(this.model, this.field); if (attribs.find(x => x.key === 'Placeholder')) { this.placeHolder = attribs.find(x => x.key === 'Placeholder').value; } if (attribs.find(x => x.key === 'ReadOnly')) { this.readonly = true; } if (attribs.find(x => x.key === 'Name')) { this.name = attribs.find(x => x.key === 'Name').value; } else { this.name = this.field; } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.3", ngImport: i0, type: NgxDropdownForComponent, deps: [{ token: i0.ElementRef }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.3", type: NgxDropdownForComponent, selector: "ngx-dropdown-for", inputs: { itemSource: "itemSource", field: "field", key: "key", valuePrimitive: "valuePrimitive", text: "text", defaultItem: "defaultItem" }, host: { properties: { "class.ngx-dropdown": "this.ngxDropdown" } }, providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: NgxDropdownForComponent, multi: true }, { provide: NG_VALIDATORS, useExisting: NgxDropdownForComponent, multi: true } ], queries: [{ propertyName: "templates", predicate: NgxCustomTemplateForDirective }], viewQueries: [{ propertyName: "ngModel", first: true, predicate: NgModel, descendants: true }], usesInheritance: true, ngImport: i0, template: "<select\n [(ngModel)]=\"value\"\n [ngStyle]=\"{'color':'red'}\"\n class=\"ngx-dropdown-child\">\n <option\n value=\"undefined\"\n disabled\n class=\"ngx-dropdown-child-default\"\n selected\n hidden\n *ngIf=\"defaultItem\">\n {{placeHolder}}\n </option>\n <ng-container *ngIf=\"valuePrimitive; else nonPrimitve\">\n <option\n *ngFor=\"let item of itemSource\"\n [ngValue]=\"item[key]\">\n {{item[text]}}\n </option>\n </ng-container>\n <ng-template #nonPrimitve>\n <option\n *ngFor=\"let item of itemSource\"\n [ngValue]=\"item\">\n {{item[text]}}\n </option>\n </ng-template>\n</select>\n", dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.3", ngImport: i0, type: NgxDropdownForComponent, decorators: [{ type: Component, args: [{ selector: 'ngx-dropdown-for', providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: NgxDropdownForComponent, multi: true }, { provide: NG_VALIDATORS, useExisting: NgxDropdownForComponent, multi: true } ], template: "<select\n [(ngModel)]=\"value\"\n [ngStyle]=\"{'color':'red'}\"\n class=\"ngx-dropdown-child\">\n <option\n value=\"undefined\"\n disabled\n class=\"ngx-dropdown-child-default\"\n selected\n hidden\n *ngIf=\"defaultItem\">\n {{placeHolder}}\n </option>\n <ng-container *ngIf=\"valuePrimitive; else nonPrimitve\">\n <option\n *ngFor=\"let item of itemSource\"\n [ngValue]=\"item[key]\">\n {{item[text]}}\n </option>\n </ng-container>\n <ng-template #nonPrimitve>\n <option\n *ngFor=\"let item of itemSource\"\n [ngValue]=\"item\">\n {{item[text]}}\n </option>\n </ng-template>\n</select>\n" }] }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Injector }], propDecorators: { ngxDropdown: [{ type: HostBinding, args: ['class.ngx-dropdown'] }], itemSource: [{ type: Input }], field: [{ type: Input }], key: [{ type: Input }], valuePrimitive: [{ type: Input }], text: [{ type: Input }], ngModel: [{ type: ViewChild, args: [NgModel, { static: false }] }], defaultItem: [{ type: Input }], templates: [{ type: ContentChildren, args: [NgxCustomTemplateForDirective, { descendants: false }] }] } }); class NgxValidatorDirective { set sk(value) { this.dataModel = value; } constructor(el) { this.el = el; this.validator = validateControl; } validate(control) { return this.validator(control, this.dataModel); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.3", ngImport: i0, type: NgxValidatorDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.3", type: NgxValidatorDirective, selector: "[ngx-validator][ngModel],[ngx-validator][formControl],[ngx-validator][formControlName]", inputs: { field: "field", sk: ["ngx-validator", "sk"] }, providers: [ { provide: NG_VALIDATORS, useExisting: NgxValidatorDirective, multi: true } ], ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.3", ngImport: i0, type: NgxValidatorDirective, decorators: [{ type: Directive, args: [{ // tslint:disable-next-line:directive-selector selector: '[ngx-validator][ngModel],[ngx-validator][formControl],[ngx-validator][formControlName]', providers: [ { provide: NG_VALIDATORS, useExisting: NgxValidatorDirective, multi: true } ] }] }], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { field: [{ type: Input }], sk: [{ type: Input, args: ['ngx-validator'] }] } }); class NgxValidatorForComponent { constructor() { this.messages = []; this.ngxLabel = true; } set errors(value) { this.messages = []; if (value) { for (const item of Object.keys(value)) { this.messages.push(value[item].toString()); } } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.3", ngImport: i0, type: NgxValidatorForComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.3", type: NgxValidatorForComponent, selector: "ngx-validator-for", inputs: { errors: "errors" }, host: { properties: { "class.ngx-validator": "this.ngxLabel" } }, ngImport: i0, template: "<div class=\"ngx-validator-child\">\n <div *ngFor=\"let message of messages\">\n <ng-container *ngIf=\"message\">{{message | translate}}</ng-container>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i2$1.TranslatePipe, name: "translate" }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.3", ngImport: i0, type: NgxValidatorForComponent, decorators: [{ type: Component, args: [{ selector: 'ngx-validator-for', template: "<div class=\"ngx-validator-child\">\n <div *ngFor=\"let message of messages\">\n <ng-container *ngIf=\"message\">{{message | translate}}</ng-container>\n </div>\n</div>\n" }] }], propDecorators: { ngxLabel: [{ type: HostBinding, args: ['class.ngx-validator'] }], errors: [{ type: Input, args: ['errors'] }] } }); class NgxLabelForComponent { constructor() { this.ngxLabel = true; this.reflectValue = ''; } ngOnInit() { try { this.reflectValue = getDecorators(this.model, this.field).find(x => x.key === 'Name').value; } catch { this.reflectValue = this.field; } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.3", ngImport: i0, type: NgxLabelForComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.3", type: NgxLabelForComponent, selector: "ngx-label-for", inputs: { model: "model", field: "field" }, host: { properties: { "class.ngx-label": "this.ngxLabel" } }, ngImport: i0, template: "<label\r\n for=\"{{field}}\"\r\n class=\"ngx-label-child\">\r\n {{reflectValue | translate}}\r\n</label>\r\n", dependencies: [{ kind: "pipe", type: i2$1.TranslatePipe, name: "translate" }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.3", ngImport: i0, type: NgxLabelForComponent, decorators: [{ type: Component, args: [{ selector: 'ngx-label-for', template: "<label\r\n for=\"{{field}}\"\r\n class=\"ngx-label-child\">\r\n {{reflectValue | translate}}\r\n</label>\r\n" }] }], propDecorators: { model: [{ type: Input }], field: [{ type: Input }], ngxLabel: [{ type: HostBinding, args: ['class.ngx-label'] }] } }); class NgxInputForComponent extends ElementBase { onFocusout() { this.blurEvent.emit(); } set templates(value) { if (this.model) { value.forEach((item) => { this._template = item; }); } } constructor(el, injector) { super(injector); this.el = el; this.injector = injector; this.DataTypeEnum = DataTypeEnum; this.placeHolder = ''; this.name = ''; this.blurEvent = new EventEmitter(); this.readonly = false; this.ngxInput = true; } ngOnInit() { if (!this.model) { console.error('ngx-validator error! [model] property is not binded!'); } if (this.field === null || this.field === undefined) { this.field = this.el.nativeElement.getAttribute('name') === null ? this.el.nativeElement.getAttribute('id') : this.el.nativeElement.getAttribute('name'); } if (!this.field) { this.field = this.el.nativeElement.getAttribute('formControlName'); } this.autocomplete = this.el.nativeElement.getAttribute('autocomplete'); const attribs = getDecorators(this.model, this.field); if (attribs.find(x => x.key === 'DataType')) { this.dataType = attribs.find(x => x.key === 'DataType').value.value; } if (attribs.find(x => x.key === 'Placeholder')) { this.placeHolder = attribs.find(x => x.key === 'Placeholder').value; } if (attribs.find(x => x.key === 'ReadOnly')) { this.readonly = true; } if (attribs.find(x => x.key === 'Name')) { this.name = attribs.find(x => x.key === 'Name').value; } else { this.name = this.field; } } getTemplate() { return this._template.templateRef; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.3", ngImport: i0, type: NgxInputForComponent, deps: [{ token: i0.ElementRef }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.3", type: NgxInputForComponent, selector: "ngx-input-for", inputs: { dataItems: "dataItems", field: "field" }, outputs: { blurEvent: "blurEvent" }, host: { listeners: { "focusout": "onFocusout()" }, properties: { "class.ngx-input": "this.ngxInput" } }, providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => NgxInputForComponent), multi: true }, { provide: NG_VALIDATORS, useExisting: NgxInputForComponent, multi: true } ], queries: [{ propertyName: "templates", predicate: NgxCustomTemplateForDirective }], viewQueries: [{ propertyName: "ngModel", first: true, predicate: NgModel, descendants: true }, { propertyName: "formControlName", first: true, predicate: FormControlName, descendants: true }], usesInheritance: true, ngImport: i0, template: "<ng-container [ngSwitch]=\"dataType\">\n <ng-container *ngIf=\"!_template; else template\">\n <a\n [href]=\"value\"\n *ngSwitchCase=\"DataTypeEnum.Url\"\n class=\"ngx-input-child-url\"\n [id]=\"field\">\n {{name | translate}}\n </a>\n <input\n type=\"password\"\n *ngSwitchCase=\"DataTypeEnum.Password\"\n [placeholder]=\"placeHolder | translate\"\n [(ngModel)]=\"value\"\n [id]=\"field\"\n autocomplete=\"{{autocomplete}}\"\n [disabled]=\"this.disabled\"\n class=\"ngx-input-child\"\n [readOnly]=\"readonly\">\n <img\n *ngSwitchCase=\"DataTypeEnum.ImageUrl\"\n [src]=\"value\"\n class=\"ngx-input-child-image\"\n [id]=\"field\">\n <input\n type=\"file\"\n *ngSwitchCase=\"DataTypeEnum.Upload\"\n [placeholder]=\"placeHolder | translate\"\n [(ngModel)]=\"value\"\n [id]=\"field\"\n autocomplete=\"{{autocomplete}}\"\n [disabled]=\"this.disabled\"\n class=\"ngx-input-child-upload\"\n [readOnly]=\"readonly\">\n <textarea\n *ngSwitchCase=\"DataTypeEnum.MultilineText\"\n [placeholder]=\"placeHolder | translate\"\n [(ngModel)]=\"value\"\n [id]=\"field\"\n [disabled]=\"this.disabled\"\n class=\"ngx-input-child-textarea\"\n rows=\"5\"\n [readOnly]=\"readonly\"></textarea>\n <input\n *ngSwitchDefault\n type=\"text\"\n [placeholder]=\"placeHolder | translate\"\n [(ngModel)]=\"value\"\n autocomplete=\"{{autocomplete}}\"\n [id]=\"field\"\n [disabled]=\"this.disabled\"\n class=\"ngx-input-child\"\n [readOnly]=\"readonly\"\n [name]=\"field\">\n </ng-container>\n <ng-template #template>\n <ng-container\n [ngTemplateOutlet]=\"getTemplate()\"\n [ngTemplateOutletContext]=\"{$implicit: model}\">\n </ng-container>\n </ng-template>\n</ng-container>\n", dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i1.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: i2$1.TranslatePipe, name: "translate" }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.3", ngImport: i0, type: NgxInputForComponent, decorators: [{ type: Component, args: [{ selector: 'ngx-input-for', providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => NgxInputForComponent), multi: true }, { provide: NG_VALIDATORS, useExisting: NgxInputForComponent, multi: true } ], template: "<ng-container [ngSwitch]=\"dataType\">\n <ng-container *ngIf=\"!_template; else template\">\n <a\n [href]=\"value\"\n *ngSwitchCase=\"DataTypeEnum.Url\"\n class=\"ngx-input-child-url\"\n [id]=\"field\">\n {{name | translate}}\n </a>\n <input\n type=\"password\"\n *ngSwitchCase=\"DataTypeEnum.Password\"\n [placeholder]=\"placeHolder | translate\"\n [(ngModel)]=\"value\"\n [id]=\"field\"\n autocomplete=\"{{autocomplete}}\"\n [disabled]=\"this.disabled\"\n class=\"ngx-input-child\"\n [readOnly]=\"readonly\">\n <img\n *ngSwitchCase=\"DataTypeEnum.ImageUrl\"\n [src]=\"value\"\n class=\"ngx-input-child-image\"\n [id]=\"field\">\n <input\n type=\"file\"\n *ngSwitchCase=\"DataTypeEnum.Upload\"\n [placeholder]=\"placeHolder | translate\"\n [(ngModel)]=\"value\"\n [id]=\"field\"\n autocomplete=\"{{autocomplete}}\"\n [disabled]=\"this.disabled\"\n class=\"ngx-input-child-upload\"\n [readOnly]=\"readonly\">\n <textarea\n *ngSwitchCase=\"DataTypeEnum.MultilineText\"\n [placeholder]=\"placeHolder | translate\"\n [(ngModel)]=\"value\"\n [id]=\"field\"\n [disabled]=\"this.disabled\"\n class=\"ngx-input-child-textarea\"\n rows=\"5\"\n [readOnly]=\"readonly\"></textarea>\n <input\n *ngSwitchDefault\n type=\"text\"\n [placeholder]=\"placeHolder | translate\"\n [(ngModel)]=\"value\"\n autocomplete=\"{{autocomplete}}\"\n [id]=\"field\"\n [disabled]=\"this.disabled\"\n class=\"ngx-input-child\"\n [readOnly]=\"readonly\"\n [name]=\"field\">\n </ng-container>\n <ng-template #template>\n <ng-container\n [ngTemplateOutlet]=\"getTemplate()\"\n [ngTemplateOutletContext]=\"{$implicit: model}\">\n </ng-container>\n </ng-template>\n</ng-container>\n" }] }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Injector }], propDecorators: { dataItems: [{ type: Input }], blurEvent: [{ type: Output }], field: [{ type: Input }], ngModel: [{ type: ViewChild, args: [NgModel, { static: false }] }], formControlName: [{ type: ViewChild, args: [FormControlName, { static: false }] }], ngxInput: [{ type: HostBinding, args: ['class.ngx-input'] }], onFocusout: [{ type: HostListener, args: ['focusout'] }], templates: [{ type: ContentChildren, args: [NgxCustomTemplateForDirective, { descendants: false }] }] } }); class NgxFormForReactiveComponent { set model(value) { this._model = value; } set formGroup(value) { this._formGroup = value; for (const item of Object.keys(this._model)) { const attribs = getDecorators(this._model, item); if (!attribs.find(x => x.key === 'NoForm') && this._formGroup.controls[item]) { this.propertyNames.push({ field: item, template: false }); } } } set templates(value) { if (this._model) { value.forEach((item) => { if (this.propertyNames.find(x => x.field === item.ngxCustomTemplateFor)) { this._templates.push(item); this.propertyNames.find(x => x.field === item.ngxCustomTemplateFor).template = true; } else { throw (new Error(`Property name bound on NgxCustomTemplateForDirective ${item.ngxCustomTemplateFor} not found. If it is definity correct, please check if you have initialized it before passing model to ngx-form-for component`)); } }); } } constructor() { this.propertyNames = []; this.submitForm = new EventEmitter(); // tslint:disable-next-line:variable-name this._templates = []; } ngOnInit() { } getTemplate(field) { return this._templates.find(x => x.ngxCustomTemplateFor === field).templateRef; } submit() { this.submitForm.emit(this._model); } controlExists(item) { if (this.formGroup.controls[item]) { return true; } else { return false; } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.3", ngImport: i0, type: NgxFormForReactiveComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.3", type: NgxFormForReactiveComponent, selector: "ngx-form-for-reactive", inputs: { cssClasses: "cssClasses", model: "model", formGroup: "formGroup", autoComplete: "autoComplete" }, outputs: { submitForm: "submitForm" }, queries: [{ propertyName: "templates", predicate: NgxCustomTemplateForDirective }], viewQueries: [{ propertyName: "form", first: true, predicate: NgForm, descendants: true }], ngImport: i0, template: "<form\n #form=\"ngForm\"\n (ngSubmit)=\"submit()\"\n [autocomplete]=\"autoComplete\"\n [formGroup]=\"_formGroup\">\n <div\n [ngClass]=\"cssClasses? cssClasses.group: 'ngx-form-for'\"\n *ngFor=\"let item of propertyNames\">\n <ng-container *ngIf=\"!item.template; else template\">\n <ngx-label-for\n [model]=\"_model\"\n [field]=\"item.field\"\n [ngClass]=\"cssClasses? cssClasses.label:''\"></ngx-label-for>\n <ngx-input-for\n [formControlName]=\"item.field\"\n [model]=\"_model\"\n [ngClass]=\"cssClasses? cssClasses.input:''\"></ngx-input-for>\n <ngx-validator-for\n [errors]=\"_formGroup.get(item.field)?.errors\"\n [ngClass]=\"cssClasses? cssClasses.error: ''\">\n </ngx-validator-for>\n </ng-container>\n <ng-template #template>\n <!-- temporary form validation workaround. custom temlpate is not binded to form's controls and therefore, form validation doesn't work. help needed -->\n <input\n [formControlName]=\"item.field\"\n [ngx-validator]=\"_model\"\n style=\"display:none\">\n <ng-container\n [ngTemplateOutlet]=\"getTemplate(item.field)\"\n [ngTemplateOutletContext]=\"{$implicit: {model: _model, form: form}}\">\n </ng-container>\n </ng-template>\n </div>\n <button\n type=\"submit\"\n [disabled]=\"form.invalid\"\n class=\"btn btn-success\">\n Submit\n </button>\n</form>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: NgxValidatorDirective, selector: "[ngx-validator][ngModel],[ngx-validator][formControl],[ngx-validator][formControlName]", inputs: ["field", "ngx-validator"] }, { kind: "component", type: NgxValidatorForComponent, selector: "ngx-validator-for", inputs: ["errors"] }, { kind: "component", type: NgxLabelForComponent, selector: "ngx-label-for", inputs: ["model", "field"] }, { kind: "component", type: NgxInputForComponent, selector: "ngx-input-for", inputs: ["dataItems", "field"], outputs: ["blurEvent"] }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.3", ngImport: i0, type: NgxFormForReactiveComponent, decorators: [{ type: Component, args: [{ selector: 'ngx-form-for-reactive', template: "<form\n #form=\"ngForm\"\n (ngSubmit)=\"submit()\"\n [autocomplete]=\"autoComplete\"\n [formGroup]=\"_formGroup\">\n <div\n [ngClass]=\"cssClasses? cssClasses.group: 'ngx-form-for'\"\n *ngFor=\"let item of propertyNames\">\n <ng-container *ngIf=\"!item.template; else template\">\n <ngx-label-for\n [model]=\"_model\"\n [field]=\"item.field\"\n [ngClass]=\"cssClasses? cssClasses.label:''\"></ngx-label-for>\n <ngx-input-for\n [formControlName]=\"item.field\"\n [model]=\"_model\"\n [ngClass]=\"cssClasses? cssClasses.input:''\"></ngx-input-for>\n <ngx-validator-for\n [errors]=\"_formGroup.get(item.field)?.errors\"\n