wfw-ngx-formly
Version:
ngx-formly is an Angular 2 module which has a Components to help customize and render JavaScript/JSON configured forms. The formly-form Component and the FormlyConfig service are very powerful and bring unmatched maintainability to your application's form
1,377 lines • 59.2 kB
JavaScript
import { __values, __spread, __extends } from 'tslib';
import { Observable, Subject } from 'rxjs';
import { Injectable, Inject, InjectionToken, Component, Input, Optional, EventEmitter, Output, SkipSelf, ViewContainerRef, ViewChild, ComponentFactoryResolver, Directive, HostListener, ElementRef, Renderer2, NgModule, ANALYZE_FOR_ENTRY_COMPONENTS } from '@angular/core';
import { FormGroup, FormArray, FormControl, AbstractControl, Validators, NgForm, FormGroupDirective, ReactiveFormsModule } from '@angular/forms';
import { debounceTime, map, tap } from 'rxjs/operators';
import { CommonModule } from '@angular/common';
function getFieldId(formId, field, index) {
if (field.id)
return field.id;
var type = field.type;
if (!type && field.template)
type = 'template';
return [formId, type, field.key, index].join('_');
}
function getKeyPath(field) {
if (!((field))['_formlyKeyPath'] || ((field))['_formlyKeyPath'].key !== field.key) {
var keyPath = [];
if (field.key) {
var pathElements = typeof field.key === 'string' ? field.key.split('.') : field.key;
try {
for (var pathElements_1 = __values(pathElements), pathElements_1_1 = pathElements_1.next(); !pathElements_1_1.done; pathElements_1_1 = pathElements_1.next()) {
var pathElement = pathElements_1_1.value;
if (typeof pathElement === 'string') {
pathElement = pathElement.replace(/\[(\w+)\]/g, '.$1');
keyPath = keyPath.concat(pathElement.split('.'));
}
else {
keyPath.push(pathElement);
}
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (pathElements_1_1 && !pathElements_1_1.done && (_a = pathElements_1.return)) _a.call(pathElements_1);
}
finally { if (e_1) throw e_1.error; }
}
for (var i = 0; i < keyPath.length; i++) {
var pathElement = keyPath[i];
if (typeof pathElement === 'string' && stringIsInteger(pathElement)) {
keyPath[i] = parseInt(pathElement);
}
}
}
((field))['_formlyKeyPath'] = {
key: field.key,
path: keyPath,
};
}
return ((field))['_formlyKeyPath'].path.slice(0);
var e_1, _a;
}
function stringIsInteger(str) {
return !isNullOrUndefined(str) && /^\d+$/.test(str);
}
var FORMLY_VALIDATORS = ['required', 'pattern', 'minLength', 'maxLength', 'min', 'max'];
function getFieldModel(model, field, constructEmptyObjects) {
var keyPath = getKeyPath(field);
var value = model;
for (var i = 0; i < keyPath.length; i++) {
var path = keyPath[i];
var pathValue = value[path];
if (isNullOrUndefined(pathValue) && constructEmptyObjects) {
if (i < keyPath.length - 1) {
value[path] = typeof keyPath[i + 1] === 'number' ? [] : {};
}
else if (field.fieldGroup && !field.fieldArray) {
value[path] = {};
}
else if (field.fieldArray) {
value[path] = [];
}
}
value = value[path];
if (!value) {
break;
}
}
return value;
}
function assignModelToFields(fields, model) {
fields.forEach(function (field, index) {
if (!isUndefined(field.defaultValue) && isUndefined(getValueForKey(model, field.key))) {
assignModelValue(model, field.key, field.defaultValue);
}
((field)).model = model;
if (field.key && (field.fieldGroup || field.fieldArray)) {
((field)).model = getFieldModel(model, field, true);
}
if (field.fieldGroup) {
assignModelToFields(field.fieldGroup, field.model);
}
});
}
function assignModelValue(model, path, value) {
if (typeof path === 'string') {
path = getKeyPath({ key: path });
}
if (path.length > 1) {
var e = path.shift();
if (!model[e] || !isObject(model[e])) {
model[e] = typeof path[0] === 'string' ? {} : [];
}
assignModelValue(model[e], path, value);
}
else {
model[path[0]] = value;
}
}
function getValueForKey(model, path) {
if (typeof path === 'string') {
path = getKeyPath({ key: path });
}
if (path.length > 1) {
var e = path.shift();
if (!model[e]) {
model[e] = typeof path[0] === 'string' ? {} : [];
}
return getValueForKey(model[e], path);
}
else {
return model[path[0]];
}
}
function reverseDeepMerge(dest) {
var args = [];
for (var _i = 1; _i < arguments.length; _i++) {
args[_i - 1] = arguments[_i];
}
args.forEach(function (src) {
for (var srcArg in src) {
if (isNullOrUndefined(dest[srcArg]) || isBlankString(dest[srcArg])) {
if (isFunction(src[srcArg])) {
dest[srcArg] = src[srcArg];
}
else {
dest[srcArg] = clone(src[srcArg]);
}
}
else if (objAndSameType(dest[srcArg], src[srcArg])) {
reverseDeepMerge(dest[srcArg], src[srcArg]);
}
}
});
return dest;
}
function isNullOrUndefined(value) {
return value === undefined || value === null;
}
function isUndefined(value) {
return value === undefined;
}
function isBlankString(value) {
return value === '';
}
function isFunction(value) {
return typeof (value) === 'function';
}
function objAndSameType(obj1, obj2) {
return isObject(obj1) && isObject(obj2) &&
Object.getPrototypeOf(obj1) === Object.getPrototypeOf(obj2);
}
function isObject(x) {
return x != null && typeof x === 'object';
}
function clone(value) {
if (!isObject(value) || value instanceof RegExp || value instanceof Observable) {
return value;
}
if (Object.prototype.toString.call(value) === '[object Date]') {
return new Date(value.getTime());
}
if (Array.isArray(value)) {
return value.slice(0).map(function (v) { return clone(v); });
}
value = Object.assign({}, value);
Object.keys(value).forEach(function (k) { return value[k] = clone(value[k]); });
return value;
}
function evalStringExpression(expression, argNames) {
try {
return Function.bind.apply(Function, [void 0].concat(argNames.concat("return " + expression + ";")))();
}
catch (error) {
console.error(error);
}
}
function evalExpressionValueSetter(expression, argNames) {
try {
return Function.bind
.apply(Function, [void 0].concat(argNames.concat(expression + " = expressionValue;")))();
}
catch (error) {
console.error(error);
}
}
function evalExpression(expression, thisArg, argVal) {
if (expression instanceof Function) {
return expression.apply(thisArg, argVal);
}
else {
return expression ? true : false;
}
}
var FORMLY_CONFIG_TOKEN = new InjectionToken('FORMLY_CONFIG_TOKEN');
var FormlyConfig = /** @class */ (function () {
function FormlyConfig(configs) {
if (configs === void 0) { configs = []; }
var _this = this;
this.types = {};
this.validators = {};
this.wrappers = {};
this.messages = {};
this.templateManipulators = {
preWrapper: [],
postWrapper: [],
};
this.extras = {
fieldTransform: undefined,
showError: function (field) {
return field.formControl && field.formControl.invalid && (field.formControl.touched || (field.options.parentForm && field.options.parentForm.submitted) || (field.field.validation && field.field.validation.show));
},
};
configs.forEach(function (config) { return _this.addConfig(config); });
}
FormlyConfig.prototype.addConfig = function (config) {
var _this = this;
if (config.types) {
config.types.forEach(function (type) { return _this.setType(type); });
}
if (config.validators) {
config.validators.forEach(function (validator) { return _this.setValidator(validator); });
}
if (config.wrappers) {
config.wrappers.forEach(function (wrapper) { return _this.setWrapper(wrapper); });
}
if (config.manipulators) {
config.manipulators.forEach(function (manipulator) { return _this.setManipulator(manipulator); });
}
if (config.validationMessages) {
config.validationMessages.forEach(function (validation) { return _this.addValidatorMessage(validation.name, validation.message); });
}
if (config.extras) {
this.extras = Object.assign({}, this.extras, config.extras);
}
};
FormlyConfig.prototype.setType = function (options) {
var _this = this;
if (Array.isArray(options)) {
options.forEach(function (option) { return _this.setType(option); });
}
else {
if (!this.types[options.name]) {
this.types[options.name] = ({});
}
this.types[options.name].component = options.component;
this.types[options.name].name = options.name;
this.types[options.name].extends = options.extends;
this.types[options.name].defaultOptions = options.defaultOptions;
if (options.wrappers) {
options.wrappers.forEach(function (wrapper) { return _this.setTypeWrapper(options.name, wrapper); });
}
}
};
FormlyConfig.prototype.getType = function (name) {
if (!this.types[name]) {
throw new Error("[Formly Error] There is no type by the name of \"" + name + "\"");
}
this.mergeExtendedType(name);
return this.types[name];
};
FormlyConfig.prototype.getMergedField = function (field) {
var _this = this;
if (field === void 0) { field = {}; }
var name = field.type;
if (!this.types[name]) {
throw new Error("[Formly Error] There is no type by the name of \"" + name + "\"");
}
this.mergeExtendedType(name);
if (this.types[name].defaultOptions) {
reverseDeepMerge(field, this.types[name].defaultOptions);
}
var extendDefaults = this.types[name].extends && this.getType(this.types[name].extends).defaultOptions;
if (extendDefaults) {
reverseDeepMerge(field, extendDefaults);
}
if (field && field.optionsTypes) {
field.optionsTypes.forEach(function (option) {
var defaultOptions = _this.getType(option).defaultOptions;
if (defaultOptions) {
reverseDeepMerge(field, defaultOptions);
}
});
}
if (!field.component) {
field.component = this.types[name].component;
}
if (!field.wrappers) {
field.wrappers = this.types[name].wrappers;
}
};
FormlyConfig.prototype.setWrapper = function (options) {
var _this = this;
this.wrappers[options.name] = options;
if (options.types) {
options.types.forEach(function (type) {
_this.setTypeWrapper(type, options.name);
});
}
};
FormlyConfig.prototype.getWrapper = function (name) {
if (!this.wrappers[name]) {
throw new Error("[Formly Error] There is no wrapper by the name of \"" + name + "\"");
}
return this.wrappers[name];
};
FormlyConfig.prototype.setTypeWrapper = function (type, name) {
if (!this.types[type]) {
this.types[type] = ({});
}
if (!this.types[type].wrappers) {
this.types[type].wrappers = ([]);
}
this.types[type].wrappers.push(name);
};
FormlyConfig.prototype.setValidator = function (options) {
this.validators[options.name] = options;
};
FormlyConfig.prototype.getValidator = function (name) {
if (!this.validators[name]) {
throw new Error("[Formly Error] There is no validator by the name of \"" + name + "\"");
}
return this.validators[name];
};
FormlyConfig.prototype.addValidatorMessage = function (name, message) {
this.messages[name] = message;
};
FormlyConfig.prototype.getValidatorMessage = function (name) {
return this.messages[name];
};
FormlyConfig.prototype.setManipulator = function (manipulator) {
new manipulator.class()[manipulator.method](this);
};
FormlyConfig.prototype.mergeExtendedType = function (name) {
if (!this.types[name].extends) {
return;
}
var extendedType = this.getType(this.types[name].extends);
if (!this.types[name].component) {
this.types[name].component = extendedType.component;
}
if (!this.types[name].wrappers) {
this.types[name].wrappers = extendedType.wrappers;
}
};
return FormlyConfig;
}());
FormlyConfig.decorators = [
{ type: Injectable },
];
FormlyConfig.ctorParameters = function () { return [
{ type: Array, decorators: [{ type: Inject, args: [FORMLY_CONFIG_TOKEN,] },] },
]; };
var FormlyFormExpression = /** @class */ (function () {
function FormlyFormExpression() {
}
FormlyFormExpression.prototype.checkFields = function (form, fields, model, options) {
if (fields === void 0) { fields = []; }
this._checkFields(form, fields, model, options);
};
FormlyFormExpression.prototype._checkFields = function (form, fields, model, options) {
var _this = this;
if (fields === void 0) { fields = []; }
fields.forEach(function (field) {
_this.checkFieldExpressionChange(form, field, _this.getParentModel(model, field), options);
_this.checkFieldVisibilityChange(form, field, _this.getParentModel(model, field), options);
if (field.fieldGroup && field.fieldGroup.length > 0) {
_this._checkFields(field.formControl ? (field.formControl) : form, field.fieldGroup, _this.getParentModel(model, field), options);
}
});
};
FormlyFormExpression.prototype.checkFieldExpressionChange = function (form, field, model, options) {
if (!field || !field.expressionProperties) {
return;
}
var expressionProperties = field.expressionProperties;
var validators = FORMLY_VALIDATORS.map(function (v) { return "templateOptions." + v; });
for (var key in expressionProperties) {
var expressionValue = evalExpression(expressionProperties[key].expression, { field: field }, [model, options.formState]);
if (expressionProperties[key].expressionValue !== expressionValue
&& (!isObject(expressionValue) || JSON.stringify(expressionValue) !== JSON.stringify(expressionProperties[key].expressionValue))) {
expressionProperties[key].expressionValue = expressionValue;
evalExpression(expressionProperties[key].expressionValueSetter, { field: field }, [expressionValue, model, field]);
if (key.indexOf('model.') === 0) {
var path = key.replace(/^model\./, ''), control = field.key && key === path ? field.formControl : form.get(path);
if (control
&& !(isNullOrUndefined(control.value) && isNullOrUndefined(expressionValue))
&& control.value !== expressionValue) {
control.patchValue(expressionValue);
}
}
if (validators.indexOf(key) !== -1 && field.formControl) {
field.formControl.updateValueAndValidity({ emitEvent: false });
}
}
}
};
FormlyFormExpression.prototype.checkFieldVisibilityChange = function (form, field, model, options) {
if (!field || isNullOrUndefined(field.hideExpression)) {
return;
}
var hideExpressionResult = !!evalExpression(field.hideExpression, { field: field }, [model, options.formState]);
if (hideExpressionResult !== field.hide) {
field.hide = hideExpressionResult;
field.templateOptions.hidden = hideExpressionResult;
if (field.formControl && field.key) {
var parent = this.fieldParentFormControl(form, field);
if (parent) {
if (hideExpressionResult === true && parent.get((this.fieldKey(field)))) {
this.removeFieldControl(parent, field);
}
else if (hideExpressionResult === false && !parent.get((this.fieldKey(field)))) {
this.addFieldControl(parent, field, model);
}
}
}
if (options.fieldChanges) {
options.fieldChanges.next(({ field: field, type: 'hidden', value: hideExpressionResult }));
}
}
};
FormlyFormExpression.prototype.addFieldControl = function (parent, field, model) {
var fieldModel = this.getFieldModel(model, field);
if (!(isNullOrUndefined(field.formControl.value) && isNullOrUndefined(fieldModel))
&& field.formControl.value !== fieldModel) {
field.formControl.patchValue(fieldModel, { emitEvent: false });
}
if (parent instanceof FormArray) {
parent.push(field.formControl);
}
else if (parent instanceof FormGroup) {
parent.addControl((this.fieldKey(field)), field.formControl);
}
};
FormlyFormExpression.prototype.getFieldModel = function (model, field) {
if (field.fieldGroup || field.fieldArray) {
return model;
}
return getFieldModel(model, field, false);
};
FormlyFormExpression.prototype.getParentModel = function (model, field) {
if (field.key && (field.fieldGroup || field.fieldArray)) {
return getFieldModel(model, field, true);
}
return model;
};
FormlyFormExpression.prototype.removeFieldControl = function (parent, field) {
if (parent instanceof FormArray) {
parent.removeAt((this.fieldKey(field)));
}
else if (parent instanceof FormGroup) {
parent.removeControl((this.fieldKey(field)));
}
};
FormlyFormExpression.prototype.fieldParentFormControl = function (form, field) {
var paths = getKeyPath(field);
paths.pop();
return ((paths.length > 0 ? form.get(paths) : form));
};
FormlyFormExpression.prototype.fieldKey = function (field) {
return getKeyPath(field).pop();
};
return FormlyFormExpression;
}());
FormlyFormExpression.decorators = [
{ type: Injectable },
];
var FormlyFormBuilder = /** @class */ (function () {
function FormlyFormBuilder(formlyConfig, formlyFormExpression) {
this.formlyConfig = formlyConfig;
this.formlyFormExpression = formlyFormExpression;
this.formId = 0;
}
FormlyFormBuilder.prototype.buildForm = function (form, fields, model, options) {
if (fields === void 0) { fields = []; }
var fieldTransforms = (options && options.fieldTransform) || this.formlyConfig.extras.fieldTransform;
if (!Array.isArray(fieldTransforms)) {
fieldTransforms = [fieldTransforms];
}
fieldTransforms.forEach(function (fieldTransform) {
if (fieldTransform) {
fields = fieldTransform(fields, model, form, options);
if (!fields) {
throw new Error('fieldTransform must return an array of fields');
}
}
});
assignModelToFields(fields, model);
this._buildForm(form, fields, options);
this.formlyFormExpression.checkFields(form, fields, model, options);
};
FormlyFormBuilder.prototype._buildForm = function (form, fields, options) {
if (fields === void 0) { fields = []; }
this.formId++;
this.registerFormControls(form, fields, options);
};
FormlyFormBuilder.prototype.registerFormControls = function (form, fields, options) {
var _this = this;
fields.forEach(function (field, index) {
field.id = getFieldId("formly_" + _this.formId, field, index);
_this.initFieldOptions(field);
_this.initFieldExpression(field, options);
_this.initFieldValidation(field);
_this.initFieldWrappers(field);
_this.initFieldAsyncValidation(field);
if (field.key && field.type) {
var paths_1 = getKeyPath({ key: field.key });
var rootForm_1 = form, rootModel_1 = field.model;
paths_1.forEach(function (path, index) {
var formPath = path.toString();
if (index === paths_1.length - 1) {
_this.addFormControl(rootForm_1, field, rootModel_1, formPath);
if (field.fieldArray) {
field.fieldGroup = [];
field.model.forEach(function (m, i) { return field.fieldGroup.push(Object.assign({}, clone(field.fieldArray), { key: "" + i })); });
assignModelToFields(field.fieldGroup, rootModel_1);
}
}
else {
var nestedForm = (rootForm_1.get(formPath));
if (!nestedForm) {
nestedForm = new FormGroup({});
_this.addControl(rootForm_1, formPath, nestedForm);
}
if (!rootModel_1[path]) {
rootModel_1[path] = typeof path === 'string' ? {} : [];
}
rootForm_1 = nestedForm;
rootModel_1 = rootModel_1[path];
}
});
}
if (field.fieldGroup) {
if (!field.type) {
field.type = 'formly-group';
}
if (field.key) {
_this.addFormControl(form, field, (_a = {}, _a[field.key] = field.fieldArray ? [] : {}, _a), field.key);
_this._buildForm((field.formControl), field.fieldGroup, options);
}
else {
if (field.hideExpression) {
field.fieldGroup.forEach(function (f) {
var hideExpression = f.hideExpression || (function () { return false; });
if (typeof hideExpression === 'string') {
hideExpression = evalStringExpression(hideExpression, ['model', 'formState']);
}
f.hideExpression = function (model, formState) { return field.hide || hideExpression(model, formState); };
});
}
_this._buildForm(form, field.fieldGroup, options);
}
}
var _a;
});
};
FormlyFormBuilder.prototype.initFieldExpression = function (field, options) {
if (field.expressionProperties) {
for (var key in (field.expressionProperties)) {
if (typeof field.expressionProperties[key] === 'string' || isFunction(field.expressionProperties[key])) {
field.expressionProperties[key] = {
expression: isFunction(field.expressionProperties[key]) ? field.expressionProperties[key] : evalStringExpression(field.expressionProperties[key], ['model', 'formState']),
expressionValueSetter: evalExpressionValueSetter("field." + key, ['expressionValue', 'model', 'field']),
};
}
}
}
if (field.hideExpression) {
delete field.hide;
if (typeof field.hideExpression === 'string') {
field.hideExpression = evalStringExpression(field.hideExpression, ['model', 'formState']);
}
}
};
FormlyFormBuilder.prototype.initFieldOptions = function (field) {
field.templateOptions = field.templateOptions || {};
if (field.type) {
this.formlyConfig.getMergedField(field);
if (field.key) {
field.templateOptions = Object.assign({
label: '',
placeholder: '',
focus: false,
}, field.templateOptions);
}
}
};
FormlyFormBuilder.prototype.initFieldAsyncValidation = function (field) {
var _this = this;
var validators = [];
if (field.asyncValidators) {
var _loop_1 = function (validatorName) {
if (validatorName !== 'validation') {
var validator_1 = field.asyncValidators[validatorName];
if (isObject(validator_1)) {
validator_1 = validator_1.expression;
}
validators.push(function (control) { return new Promise(function (resolve) {
return validator_1(control, field).then(function (result) {
resolve(result ? null : (_a = {}, _a[validatorName] = true, _a));
var _a;
});
}); });
}
};
for (var validatorName in field.asyncValidators) {
_loop_1(validatorName);
}
}
if (field.asyncValidators && Array.isArray(field.asyncValidators.validation)) {
field.asyncValidators.validation
.forEach(function (validator) { return validators.push(_this.wrapNgValidatorFn(field, validator)); });
}
if (validators.length) {
if (field.asyncValidators && !Array.isArray(field.asyncValidators.validation)) {
field.asyncValidators.validation = Validators.composeAsync(__spread([field.asyncValidators.validation], validators));
}
else {
field.asyncValidators = {
validation: Validators.composeAsync(validators),
};
}
}
};
FormlyFormBuilder.prototype.initFieldValidation = function (field) {
var _this = this;
var validators = [];
FORMLY_VALIDATORS
.filter(function (opt) { return (field.templateOptions && field.templateOptions.hasOwnProperty(opt))
|| (field.expressionProperties && field.expressionProperties["templateOptions." + opt]); })
.forEach(function (opt) {
validators.push(function (control) {
if (field.templateOptions[opt] === false) {
return null;
}
return _this.getValidation(opt, field.templateOptions[opt])(control);
});
});
if (field.validators) {
var _loop_2 = function (validatorName) {
if (validatorName !== 'validation') {
var validator_2 = field.validators[validatorName];
if (isObject(validator_2)) {
validator_2 = validator_2.expression;
}
validators.push(function (control) {
return validator_2(control, field) ? null : (_a = {}, _a[validatorName] = true, _a);
var _a;
});
}
};
for (var validatorName in field.validators) {
_loop_2(validatorName);
}
}
if (field.validators && Array.isArray(field.validators.validation)) {
field.validators.validation
.forEach(function (validator) { return validators.push(_this.wrapNgValidatorFn(field, validator)); });
}
if (validators.length) {
if (field.validators && !Array.isArray(field.validators.validation)) {
field.validators.validation = Validators.compose(__spread([field.validators.validation], validators));
}
else {
field.validators = {
validation: Validators.compose(validators),
};
}
}
};
FormlyFormBuilder.prototype.addFormControl = function (form, field, model, path) {
var control;
var validators = field.validators ? field.validators.validation : undefined, asyncValidators = field.asyncValidators ? field.asyncValidators.validation : undefined, updateOn = field.modelOptions && field.modelOptions.updateOn ?
field.modelOptions.updateOn : undefined;
var abstractControlOptions = ({
validators: validators,
asyncValidators: asyncValidators,
updateOn: updateOn,
});
if (field.formControl instanceof AbstractControl || form.get(path)) {
control = field.formControl || form.get(path);
if (!(isNullOrUndefined(control.value) && isNullOrUndefined(model[path]))
&& control.value !== model[path]
&& control instanceof FormControl) {
control.patchValue(model[path]);
}
}
else if (field.component && field.component.createControl) {
control = field.component.createControl(model[path], field);
}
else if (field.fieldGroup && field.key && field.key === path && !field.fieldArray) {
control = new FormGroup(model[path], abstractControlOptions);
}
else if (field.fieldArray && field.key && field.key === path) {
control = new FormArray([], abstractControlOptions);
}
else {
control = new FormControl(model[path], abstractControlOptions);
}
if (field.templateOptions.disabled) {
control.disable();
}
if (delete field.templateOptions.disabled) {
Object.defineProperty(field.templateOptions, 'disabled', {
get: (function () { return !this.formControl.enabled; }).bind(field),
set: (function (value) {
if (this.expressionProperties && this.expressionProperties.hasOwnProperty('templateOptions.disabled')) {
this.expressionProperties['templateOptions.disabled'].expressionValue = value;
}
value ? this.formControl.disable() : this.formControl.enable();
}).bind(field),
enumerable: true,
configurable: true,
});
}
this.addControl(form, path, control, field);
};
FormlyFormBuilder.prototype.addControl = function (form, key, formControl, field) {
if (field) {
field.formControl = formControl;
}
if (form instanceof FormArray) {
if (form.at((key)) !== formControl) {
form.setControl((key), formControl);
}
}
else {
if (form.get((key)) !== formControl) {
form.setControl((key), formControl);
}
}
};
FormlyFormBuilder.prototype.getValidation = function (opt, value) {
switch (opt) {
case 'required':
return Validators.required;
case 'pattern':
return Validators.pattern(value);
case 'minLength':
return Validators.minLength(value);
case 'maxLength':
return Validators.maxLength(value);
case 'min':
return Validators.min(value);
case 'max':
return Validators.max(value);
}
};
FormlyFormBuilder.prototype.wrapNgValidatorFn = function (field, validator) {
validator = typeof validator === 'string'
? this.formlyConfig.getValidator(validator).validation
: validator;
return function (control) { return ((validator))(control, field); };
};
FormlyFormBuilder.prototype.initFieldWrappers = function (field) {
var templateManipulators = {
preWrapper: [],
postWrapper: [],
};
if (field.templateOptions) {
this.mergeTemplateManipulators(templateManipulators, field.templateOptions.templateManipulators);
}
this.mergeTemplateManipulators(templateManipulators, this.formlyConfig.templateManipulators);
var preWrappers = templateManipulators.preWrapper.map(function (m) { return m(field); }).filter(function (type) { return type; }), postWrappers = templateManipulators.postWrapper.map(function (m) { return m(field); }).filter(function (type) { return type; });
if (!field.wrappers) {
field.wrappers = [];
}
field.wrappers = __spread(preWrappers, (field.wrappers || []), postWrappers);
};
FormlyFormBuilder.prototype.mergeTemplateManipulators = function (source, target) {
target = target || {};
if (target.preWrapper) {
source.preWrapper = source.preWrapper.concat(target.preWrapper);
}
if (target.postWrapper) {
source.postWrapper = source.postWrapper.concat(target.postWrapper);
}
return source;
};
return FormlyFormBuilder;
}());
FormlyFormBuilder.decorators = [
{ type: Injectable },
];
FormlyFormBuilder.ctorParameters = function () { return [
{ type: FormlyConfig, },
{ type: FormlyFormExpression, },
]; };
var FormlyForm = /** @class */ (function () {
function FormlyForm(formlyBuilder, formlyExpression, formlyConfig, parentForm, parentFormGroup, parentFormlyForm) {
this.formlyBuilder = formlyBuilder;
this.formlyExpression = formlyExpression;
this.formlyConfig = formlyConfig;
this.parentForm = parentForm;
this.parentFormGroup = parentFormGroup;
this.parentFormlyForm = parentFormlyForm;
this.model = {};
this.form = new FormGroup({});
this.fields = [];
this.modelChange = new EventEmitter();
this.modelWillChange = new EventEmitter();
this.modelDidChange = new EventEmitter();
this.isRoot = true;
this.modelChangeSubs = [];
}
FormlyForm.prototype.ngDoCheck = function () {
this.checkExpressionChange();
};
FormlyForm.prototype.ngOnChanges = function (changes) {
if (!this.fields || this.fields.length === 0 || !this.isRoot) {
return;
}
if (changes["fields"] || changes["form"]) {
this.modelWillChange.emit();
this.model = this.model || {};
this.form = this.form || (new FormGroup({}));
this.setOptions();
this.clearModelSubscriptions();
((this.options)).components = [];
this.formlyBuilder.buildForm(this.form, this.fields, this.model, this.options);
this.trackModelChanges(this.fields);
this.updateInitialValue();
this.modelDidChange.emit();
}
else if (changes["model"]) {
this.modelWillChange.emit();
this.patchModel(this.model);
this.modelDidChange.emit();
}
};
FormlyForm.prototype.ngOnDestroy = function () {
this.clearModelSubscriptions();
};
FormlyForm.prototype.changeModel = function (event) {
assignModelValue(this.model, event.key, event.value);
this.modelChange.emit(this.model);
this.checkExpressionChange();
};
FormlyForm.prototype.setOptions = function () {
var _this = this;
this.options = this.options || {};
this.options.formState = this.options.formState || {};
if (!this.options.showError) {
this.options.showError = this.formlyConfig.extras.showError;
}
if (!this.options.fieldChanges) {
this.options.fieldChanges = new Subject();
}
if (!this.options.resetModel) {
this.options.resetModel = this.resetModel.bind(this);
}
if (!this.options.parentForm) {
this.options.parentForm = this.parentFormGroup || this.parentForm;
}
if (!this.options.updateInitialValue) {
this.options.updateInitialValue = this.updateInitialValue.bind(this);
}
if (!((this.options)).resetTrackModelChanges) {
((this.options)).resetTrackModelChanges = function () {
_this.clearModelSubscriptions();
_this.trackModelChanges(_this.fields);
};
}
};
FormlyForm.prototype.checkExpressionChange = function () {
if (this.isRoot) {
this.formlyExpression.checkFields(this.form, this.fields, this.model, this.options);
}
};
FormlyForm.prototype.trackModelChanges = function (fields, rootKey) {
var _this = this;
if (rootKey === void 0) { rootKey = []; }
fields.forEach(function (field) {
if (field.key && field.type && !field.fieldGroup && !field.fieldArray) {
var valueChanges = field.formControl.valueChanges.pipe(field.modelOptions && field.modelOptions.debounce && field.modelOptions.debounce.default
? debounceTime(field.modelOptions.debounce.default)
: tap(function () { }), map(function (value) {
if (field.parsers && field.parsers.length > 0) {
field.parsers.forEach(function (parserFn) { return value = parserFn(value); });
}
return value;
}), tap(function (value) { return _this.changeModel({ key: __spread(rootKey, [field.key]).join('.'), value: value }); }));
_this.modelChangeSubs.push(valueChanges.subscribe());
}
if (field.fieldGroup && field.fieldGroup.length > 0) {
_this.trackModelChanges(field.fieldGroup, field.key ? __spread(rootKey, [field.key]) : rootKey);
}
});
};
FormlyForm.prototype.clearModelSubscriptions = function () {
this.modelChangeSubs.forEach(function (sub) { return sub.unsubscribe(); });
this.modelChangeSubs = [];
};
FormlyForm.prototype.patchModel = function (model) {
this.clearModelSubscriptions();
this.resetFieldArray(this.fields, model);
this.initializeFormValue(this.form);
((this.form)).patchValue(model, { onlySelf: true });
this.trackModelChanges(this.fields);
};
FormlyForm.prototype.resetModel = function (model) {
this.modelWillChange.emit();
((this.options)).components.forEach(function (component) {
if (component.onBeforePatchValue) {
component.onBeforePatchValue();
}
});
model = isNullOrUndefined(model) ? this.initialModel : model;
this.resetFieldArray(this.fields, model);
if (!this.parentFormlyForm && this.options.parentForm && this.options.parentForm.control === this.form) {
this.options.parentForm.resetForm(model);
}
else {
this.form.reset(model);
}
this.modelDidChange.emit();
};
FormlyForm.prototype.resetFieldArray = function (fields, newModel) {
var _this = this;
fields.forEach(function (field) {
if ((field.fieldGroup && field.fieldGroup.length > 0) || field.fieldArray) {
var newFieldModel_1 = getFieldModel(newModel, field, true);
if (field.fieldArray) {
field.fieldGroup = field.fieldGroup || [];
field.fieldGroup.length = 0;
if (field.model !== newFieldModel_1 && field.model) {
field.model.length = 0;
}
var formControl_1 = (field.formControl);
while (formControl_1.length !== 0) {
formControl_1.removeAt(0);
}
newFieldModel_1.forEach(function (m, i) {
field.model[i] = m;
field.fieldGroup.push(Object.assign({}, clone(field.fieldArray), { key: "" + i }));
_this.formlyBuilder.buildForm(formControl_1, [field.fieldGroup[i]], newFieldModel_1, _this.options);
});
}
else {
_this.resetFieldArray(field.fieldGroup, newFieldModel_1);
}
}
else if (field.key && field.type) {
field.formControl.reset(getFieldModel(newModel, field, false));
}
});
};
FormlyForm.prototype.initializeFormValue = function (control) {
var _this = this;
if (control instanceof FormControl) {
control.setValue(null);
}
else if (control instanceof FormGroup) {
Object.keys(control.controls).forEach(function (k) { return _this.initializeFormValue(control.controls[k]); });
}
else if (control instanceof FormArray) {
control.controls.forEach(function (c) { return _this.initializeFormValue(c); });
}
};
FormlyForm.prototype.updateInitialValue = function () {
this.initialModel = reverseDeepMerge({}, this.model);
};
return FormlyForm;
}());
FormlyForm.decorators = [
{ type: Component, args: [{
selector: 'formly-form',
template: "\n <formly-field *ngFor=\"let field of fields\"\n [model]=\"field.model\" [form]=\"form\"\n [field]=\"field\"\n [ngClass]=\"field.className\"\n [options]=\"options\">\n </formly-field>\n <ng-content></ng-content>\n ",
},] },
];
FormlyForm.ctorParameters = function () { return [
{ type: FormlyFormBuilder, },
{ type: FormlyFormExpression, },
{ type: FormlyConfig, },
{ type: NgForm, decorators: [{ type: Optional },] },
{ type: FormGroupDirective, decorators: [{ type: Optional },] },
{ type: FormlyForm, decorators: [{ type: Optional }, { type: SkipSelf },] },
]; };
FormlyForm.propDecorators = {
"model": [{ type: Input },],
"form": [{ type: Input },],
"fields": [{ type: Input },],
"options": [{ type: Input },],
"modelChange": [{ type: Output },],
"modelWillChange": [{ type: Output },],
"modelDidChange": [{ type: Output },],
"isRoot": [{ type: Input },],
};
var FormlyField = /** @class */ (function () {
function FormlyField(formlyConfig, componentFactoryResolver) {
this.formlyConfig = formlyConfig;
this.componentFactoryResolver = componentFactoryResolver;
this.options = {};
this.modelChange = new EventEmitter();
this.componentRefs = [];
}
FormlyField.prototype.ngAfterContentInit = function () {
this.lifeCycleHooks(this.lifecycle.afterContentInit);
};
FormlyField.prototype.ngAfterContentChecked = function () {
this.lifeCycleHooks(this.lifecycle.afterContentChecked);
};
FormlyField.prototype.ngAfterViewInit = function () {
this.lifeCycleHooks(this.lifecycle.afterViewInit);
};
FormlyField.prototype.ngAfterViewChecked = function () {
this.lifeCycleHooks(this.lifecycle.afterViewChecked);
};
FormlyField.prototype.ngDoCheck = function () {
this.lifeCycleHooks(this.lifecycle.doCheck);
};
FormlyField.prototype.ngOnInit = function () {
if (!this.field.template) {
this.createFieldComponent();
}
this.lifeCycleHooks(this.lifecycle.onInit);
};
FormlyField.prototype.ngOnChanges = function (changes) {
var _this = this;
this.lifeCycleHooks(this.lifecycle.onChanges);
this.componentRefs.forEach(function (ref) {
Object.assign(ref.instance, {
model: _this.model,
form: _this.form,
field: _this.field,
options: _this.options,
});
});
};
FormlyField.prototype.ngOnDestroy = function () {
this.lifeCycleHooks(this.lifecycle.onDestroy);
this.componentRefs.forEach(function (componentRef) { return componentRef.destroy(); });
this.componentRefs = [];
};
FormlyField.prototype.createFieldComponent = function () {
var _this = this;
var type = this.formlyConfig.getType(this.field.type);
var fieldComponent = this.fieldComponent;
(this.field.wrappers || []).forEach(function (wrapperName) {
var wrapperRef = _this.createComponent(fieldComponent, _this.formlyConfig.getWrapper(wrapperName).component);
fieldComponent = wrapperRef.instance.fieldComponent;
});
return this.createComponent(fieldComponent, type.component);
};
FormlyField.prototype.createComponent = function (fieldComponent, component) {
var componentFactory = this.componentFactoryResolver.resolveComponentFactory(component);
var ref = (fieldComponent.createComponent(componentFactory));
Object.assign(ref.instance, {
model: this.model,
form: this.form,
field: this.field,
options: this.options,
});
var optionsComponents = ((this.options)).components;
if (optionsComponents) {
optionsComponents.push(ref.instance);
}
this.componentRefs.push(ref);
return ref;
};
Object.defineProperty(FormlyField.prototype, "lifecycle", {
get: function () {
return this.field.lifecycle || {};
},
enumerable: true,
configurable: true
});
FormlyField.prototype.lifeCycleHooks = function (callback) {
if (callback) {
callback(this.form, this.field, this.model, this.options);
}
};
return FormlyField;
}());
FormlyField.decorators = [
{ type: Component, args: [{
selector: 'formly-field',
template: "\n <ng-template #fieldComponent></ng-template>\n <div *ngIf=\"field.template && !field.fieldGroup\" [innerHtml]=\"field.template\"></div>\n ",
host: {
'[style.display]': 'field.hide ? "none":""',
},
},] },
];
FormlyField.ctorParameters = function () { return [
{ type: FormlyConfig, },
{ type: ComponentFactoryResolver, },
]; };
FormlyField.propDecorators = {
"model": [{ type: Input },],
"form": [{ type: Input },],
"field": [{ type: Input },],
"options": [{ type: Input },],
"modelChange": [{ type: Output },],
"fieldComponent": [{ type: ViewChild, args: ['fieldComponent', { read: ViewContainerRef },] },],
};
var FormlyAttributes = /** @class */ (function () {
function FormlyAttributes(renderer, elementRef) {
this.renderer = renderer;
this.elementRef = elementRef;
this.attributes = ['id', 'name', 'placeholder', 'tabindex', 'step', 'readonly'];
this.statements = ['change', 'keydown', 'keyup', 'keypress', 'click', 'focus', 'blur'];
}
FormlyAttributes.prototype.onFocus = function () {
this.field.focus = true;
};
FormlyAttributes.prototype.onBlur = function () {
this.field.focus = false;
};
FormlyAttributes.prototype.ngOnChanges = function (changes) {
var _this = this;
if (changes["field"]) {
var fieldChanges_1 = changes["field"];
this.attributes
.filter(function (attr) { return _this.canApplyRender(fieldChanges_1, attr); })
.forEach(function (attr) { return _this.renderer.setAttribute(_this.elementRef.nativeElement, attr, _this.getPropValue(_this.field, attr)); });
if (this.field.templateOptions && this.field.templateOptions.attributes) {
var attributes_1 = this.field.templateOptions.attributes;
Object.keys(attributes_1).forEach(function (name) { return _this.renderer.setAttribute(_this.elementRef.nativeElement, name, (attributes_1[name])); });
}
this.statements
.filter(function (statement) { return _this.canApplyRender(fieldChanges_1, statement); })
.forEach(function (statement) { return _this.renderer.listen(_this.elementRef.nativeElement, statement, _this.getStatementValue(statement)); });
if ((fieldChanges_1.previousValue || {}).focus !== (fieldChanges_1.currentValue || {}).focus && this.elementRef.nativeElement.focus) {
this.elementRef.nativeElement[this.field.focus ? 'focus' : 'blur']();
}
}
};
FormlyAttributes.prototype.getPropValue = function (field, prop) {
field = field || {};
if (field.templateOptions && field.templateOptions[prop]) {
return field.templateOptions[prop];
}
return ((field))[prop] || '';
};
FormlyAttributes.prototype.getStatementValue = function (statement) {
var _this = this;
var fn = this.field.templateOptions[statement];
return function (event) { return fn(_this.field, event); };
};
FormlyAttributes.prototype.canApplyRender = function (fieldChange, prop) {
var currentValue = this.getPropValue(this.field, prop), previousValue = this.getPropValue(fieldChange.previousValue, prop);
if (previousValue !== currentValue) {
if (this.statements.indexOf(prop) !== -1) {
return typeof currentValue === 'function';
}
return true;
}
return false;
};
return FormlyAttributes;
}());
FormlyAttributes.decorators = [
{ type: Directive, args: [{
selector: '[formlyAttributes]',
},] },
];
FormlyAttributes.ctorParameters = function () { return [
{ type: Renderer2, },
{ type: ElementRef, },
]; };
FormlyAttributes.propDecorators = {
"field": [{ type: Input, args: ['formlyAttributes',] },],
"onFocus": [{ type: HostListener, args: ['focus',] },],
"onBlur": [{ type: HostListener, args: ['blur',] },],
};
var Field = /** @class */ (function () {
function Field() {
}
Object.defineProperty(Field.prototype, "key", {
get: function () { return this.field.key; },
enumerable: true,
configurable: true
});
Object.defineProperty(Field.prototype, "formControl", {
get: function () { return this.field.formControl; },
enumerable: true,
configurable: true
});
Object.defineProperty(Field.prototype, "to", {
get: function () { return this.field.templateOptions; },
enumerable: true,
configurable: true
});
Object.defineProperty(Field.prototype, "showError", {
get: function () { return this.options.showError(this); },
enumerable: true,
configurable: true
});
Object.defineProperty(Field.prototype, "id", {
get: function () { return this.field.id; },
enumerable: true,
configurable: true
});
Object.defineProperty(Field.prototype, "formState", {
get: function () { return this.options.formState || {}; },
enumerable: true,
configurable: true
});
Field.prototype.onBeforePatchValue = function () { };
return Field;
}());
Field.propDecorators = {
"form": [{ type: Input },],
"field": [{ type: Input },],
"model": [{ type: Input },],
"options": [{ type: Input },],
};
var FieldType = /** @class */ (function (_super) {
__extends(FieldType, _super);
function FieldType() {
return _super !== null && _super.apply(this, arguments) || this;
}
FieldType.prototype.ngOnInit = function () { };
FieldType.prototype.ngOnChanges = function (changes) { };
FieldType.prototype.ngDoCheck = function () { };
FieldType.prototype.ngAfterContentInit = function () { };
FieldType.prototype.ngAfterContentChecked = function () { };
FieldType.prototype.ngAfterViewInit = function () { };
FieldType.prototype.ngAfterViewChecked = function () { };
FieldType.prototype.ngOnDestroy = function () { };
return FieldType;
}(Field));
var FieldArrayType = /** @class */ (function (_super) {
__extends(FieldArrayType, _super);
function FieldArrayType(builder) {
var _this = _super.call(this) || this;
_this.builder = builder;
return _this;
}
FieldArrayType.prototype.add = function (i, initialModel) {
i = isNullOrUndefined(i) ? this.field.fieldGroup.length : i;
this.model.splice(i, 0, initialModel ? clone(initialModel) : undefined);
this.field.fieldGroup.splice(i, 0, Object.assign({}, clone(this.field.fieldArray)));
this.field.fieldGroup.forEach(function (field, index) {
field.key = "" + index;
});
var form = new FormArray([]);
this.builder.buildForm(form, [this.field.fieldGroup[i]], this.model, this.options);
this.formControl.insert(i, form.at(0));
((this.options)).resetTrackModelChanges();
};
FieldArrayType.prototype.remove = function (i) {
this.formControl.removeAt(i);
this.field.fieldGroup.splice(i, 1);
this.field.fieldGroup.forEach(function (f, index) { return f.key = "" + index; });
this.model.splice(i, 1);
((this.options)).resetTrackModelChanges();
};
return FieldArrayType;
}(FieldType));
var FieldWrapper = /** @class */ (function (_super) {
__extends(FieldWrapper, _super);
function FieldWrapper() {
return _super !== null && _super.apply(this, arguments) || this;
}
return FieldWrapper;
}(Field));
var FormlyGroup = /** @class */ (function (_super) {
__extends(FormlyGroup, _super);
function FormlyGroup() {
return _super !== null && _super.apply(this, arguments) || this;
}
return FormlyGroup;
}(FieldType));
FormlyGroup.decorators = [
{ type: Component, args: [{
selector: 'formly-group',
template: "\n <formly-form\n [fields]=\"field.fieldGroup\"\n [isRoot]=\"false\"\n [model]=\"model\"\n [form]=\"field.formControl || form\"\n [options]=\"options\"\n [ngClass]=\"field.fieldGroupClassName\">\n <ng-content></ng-content>\n </formly-form>\n ",
},] },
];
var FormlyValidationMessage = /** @class */ (function () {
function FormlyValidationMessage(formlyConfig) {
this.formlyConfig = formlyConfig;
}
Object.defineProperty(FormlyValidationMessage.prototype, "fieldForm", {
set: function (control) {
console.warn("formly-validation-message: Passing 'fieldForm' input is deprecated and it will be removed in the 4.0 version.");
},
enumerable: true,
configurable: true
});
Object.defineProperty(FormlyValidationMessage.prototype, "errorMessage", {
get: function () {
var fieldForm = this.field.formControl;
for (var error in fieldForm.errors) {
if (fieldForm.errors.hasOwnProperty(error)) {
var message = this.formlyConfig.getValidatorMessage(error);
if (this.field.validation && this.field.validation.messages && this.field.validation.messages[error]) {
message = this.field.validation.messages[error];
}
if (this.field.validators && this.field.validators[error] && this.field.validators[error].message) {
message = this.field.validators[error].message;
}
if (this.field.asyncValidators && this.field.asyncValidators[error] && this.field.asyncValidators[error].message) {
message = this.field.asyncValidators[error].message;
}
if (typeof message === 'function') {
return message(fieldForm.errors[error], this.field);
}
return message;
}
}
},
enumerable: true,
configurable: true
});
return FormlyValidationMessage;
}());
FormlyValidationMessage.decorators = [
{ type: Component, args: [{
selector: 'formly-validation-message',
template: "{{ errorMessage }}",
},] },
];
FormlyValidationMessage.ctorParameters = function () { return [
{ type: FormlyConfig, },
]; };
FormlyValidationMessage.propDecorators = {
"field": [{ type: Input },],
"fieldForm": [{ type: Input },],
};
var FormlyModule = /** @class */ (function () {
function FormlyModule() {
}
FormlyModule.forRoot = function (config) {
if (config === void 0) { config = {}; }
return {
ngModule: FormlyModule,
providers: [
FormlyFormBuilder,
FormlyFormExpression,
FormlyConfig,
{ provide: FORMLY_CONFIG_TOKEN, useValue: { types: [{ name: 'formly-group', component: FormlyGroup }] }, multi: true },
{ provide: FORMLY_CONFIG_TOKEN, useValue: config, multi: true },
{ provide: ANALYZE_FOR_ENTRY_COMPONENTS, useValue: config, multi: true },
],
};
};
FormlyModule.forChild = function (config) {
if (config === void 0) { config = {}; }
return {
ngModule: FormlyModule,
providers: [
{ provide: FORMLY_CONFIG_TOKEN, useValue: config, multi: true },
{ provide: ANALYZE_FOR_ENTRY_COMPONENTS, useValue: config, multi: true },
],
};
};
return FormlyModule;
}());
FormlyModule.decorators = [
{ type: NgModule, args: [{
declarations: [FormlyForm, FormlyField, FormlyAttributes, FormlyGroup, FormlyValidationMessage],
entryComponents: [FormlyGroup],
exports: [FormlyForm, FormlyField, FormlyAttributes, FormlyGroup, FormlyValidationMessage],
imports: [
CommonModule,
ReactiveFormsModule,
],
},] },
];
export { FormlyForm, FormlyField, FormlyAttributes, FormlyConfig, FormlyFormBuilder, Field, FieldType, FieldArrayType, FieldWrapper, FormlyModule, FormlyGroup as ɵc, FORMLY_CONFIG_TOKEN as ɵa, FormlyFormExpression as ɵb, FormlyValidationMessage as ɵd };
//# sourceMappingURL=wfw-ngx-formly.js.map