UNPKG

angular2-schema-form

Version:

Angular2 Schema Form (DISCLAIMER: it is not related to angular-schema-form)

274 lines (273 loc) 10 kB
var __extends = (this && this.__extends) || (function () { var extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); import { Observable } from 'rxjs/Observable'; import { BehaviorSubject } from 'rxjs/BehaviorSubject'; import 'rxjs/add/observable/combineLatest'; import 'rxjs/add/operator/map'; import 'rxjs/add/operator/do'; import 'rxjs/add/operator/distinctUntilChanged'; var FormProperty = (function () { function FormProperty(schemaValidatorFactory, validatorRegistry, schema, parent, path) { this.validatorRegistry = validatorRegistry; this.schema = schema; this._value = null; this._errors = null; this._valueChanges = new BehaviorSubject(null); this._errorsChanges = new BehaviorSubject(null); this._visible = true; this._visibilityChanges = new BehaviorSubject(true); this.schemaValidator = schemaValidatorFactory.createValidatorFn(this.schema); this._parent = parent; if (parent) { this._root = parent.root; } else if (this instanceof PropertyGroup) { this._root = this; } this._path = path; } Object.defineProperty(FormProperty.prototype, "valueChanges", { get: function () { return this._valueChanges; }, enumerable: true, configurable: true }); Object.defineProperty(FormProperty.prototype, "errorsChanges", { get: function () { return this._errorsChanges; }, enumerable: true, configurable: true }); Object.defineProperty(FormProperty.prototype, "type", { get: function () { return this.schema.type; }, enumerable: true, configurable: true }); Object.defineProperty(FormProperty.prototype, "parent", { get: function () { return this._parent; }, enumerable: true, configurable: true }); Object.defineProperty(FormProperty.prototype, "root", { get: function () { return this._root || this; }, enumerable: true, configurable: true }); Object.defineProperty(FormProperty.prototype, "path", { get: function () { return this._path; }, enumerable: true, configurable: true }); Object.defineProperty(FormProperty.prototype, "value", { get: function () { return this._value; }, enumerable: true, configurable: true }); Object.defineProperty(FormProperty.prototype, "visible", { get: function () { return this._visible; }, enumerable: true, configurable: true }); Object.defineProperty(FormProperty.prototype, "valid", { get: function () { return this._errors === null; }, enumerable: true, configurable: true }); FormProperty.prototype.updateValueAndValidity = function (onlySelf, emitEvent) { if (onlySelf === void 0) { onlySelf = false; } if (emitEvent === void 0) { emitEvent = true; } this._updateValue(); if (emitEvent) { this.valueChanges.next(this.value); } this._runValidation(); if (this.parent && !onlySelf) { this.parent.updateValueAndValidity(onlySelf, emitEvent); } }; /** * @internal */ FormProperty.prototype._runValidation = function () { var errors = this.schemaValidator(this._value) || []; var customValidator = this.validatorRegistry.get(this.path); if (customValidator) { var customErrors = customValidator(this.value, this, this.findRoot()); errors = this.mergeErrors(errors, customErrors); } if (errors.length === 0) { errors = null; } this._errors = errors; this.setErrors(this._errors); }; FormProperty.prototype.mergeErrors = function (errors, newErrors) { if (newErrors) { if (Array.isArray(newErrors)) { errors = errors.concat.apply(errors, newErrors); } else { errors.push(newErrors); } } return errors; }; FormProperty.prototype.setErrors = function (errors) { this._errors = errors; this._errorsChanges.next(errors); }; FormProperty.prototype.extendErrors = function (errors) { errors = this.mergeErrors(this._errors || [], errors); this.setErrors(errors); }; FormProperty.prototype.searchProperty = function (path) { var prop = this; var base = null; var result = null; if (path[0] === '/') { base = this.findRoot(); result = base.getProperty(path.substr(1)); } else { while (result === null && prop.parent !== null) { prop = base = prop.parent; result = base.getProperty(path); } } return result; }; FormProperty.prototype.findRoot = function () { var property = this; while (property.parent !== null) { property = property.parent; } return property; }; FormProperty.prototype.setVisible = function (visible) { this._visible = visible; this._visibilityChanges.next(visible); this.updateValueAndValidity(); if (this.parent) { this.parent.updateValueAndValidity(false, true); } }; // A field is visible if AT LEAST ONE of the properties it depends on is visible AND has a value in the list FormProperty.prototype._bindVisibility = function () { var _this = this; var visibleIf = this.schema.visibleIf; if (typeof visibleIf === 'object' && Object.keys(visibleIf).length === 0) { this.setVisible(false); } else if (visibleIf !== undefined) { var propertiesBinding = []; var _loop_1 = function (dependencyPath) { if (visibleIf.hasOwnProperty(dependencyPath)) { var property = this_1.searchProperty(dependencyPath); if (property) { var valueCheck = property.valueChanges.map(function (value) { if (visibleIf[dependencyPath].indexOf('$ANY$') !== -1) { return value.length > 0; } else { return visibleIf[dependencyPath].indexOf(value) !== -1; } }); var visibilityCheck = property._visibilityChanges; var and = Observable.combineLatest([valueCheck, visibilityCheck], function (v1, v2) { return v1 && v2; }); propertiesBinding.push(and); } else { console.warn('Can\'t find property ' + dependencyPath + ' for visibility check of ' + this_1.path); } } }; var this_1 = this; for (var dependencyPath in visibleIf) { _loop_1(dependencyPath); } Observable.combineLatest(propertiesBinding, function () { var values = []; for (var _i = 0; _i < arguments.length; _i++) { values[_i] = arguments[_i]; } return values.indexOf(true) !== -1; }).distinctUntilChanged().subscribe(function (visible) { _this.setVisible(visible); }); } }; return FormProperty; }()); export { FormProperty }; var PropertyGroup = (function (_super) { __extends(PropertyGroup, _super); function PropertyGroup() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.properties = null; return _this; } PropertyGroup.prototype.getProperty = function (path) { var subPathIdx = path.indexOf('/'); var propertyId = subPathIdx !== -1 ? path.substr(0, subPathIdx) : path; var property = this.properties[propertyId]; if (property !== null && subPathIdx !== -1 && property instanceof PropertyGroup) { var subPath = path.substr(subPathIdx + 1); property = property.getProperty(subPath); } return property; }; PropertyGroup.prototype.forEachChild = function (fn) { for (var propertyId in this.properties) { if (this.properties.hasOwnProperty(propertyId)) { var property = this.properties[propertyId]; fn(property, propertyId); } } }; PropertyGroup.prototype.forEachChildRecursive = function (fn) { this.forEachChild(function (child) { fn(child); if (child instanceof PropertyGroup) { child.forEachChildRecursive(fn); } }); }; PropertyGroup.prototype._bindVisibility = function () { _super.prototype._bindVisibility.call(this); this._bindVisibilityRecursive(); }; PropertyGroup.prototype._bindVisibilityRecursive = function () { this.forEachChildRecursive(function (property) { property._bindVisibility(); }); }; PropertyGroup.prototype.isRoot = function () { return this === this.root; }; return PropertyGroup; }(FormProperty)); export { PropertyGroup };