UNPKG

@crnk/angular-ngrx

Version:

Angular helper library for ngrx-json-api and crnk:

170 lines 7.11 kB
// copy/pasted from @angular/forms to due the lack of customizability of their implementation import { AbstractControl, AbstractControlDirective, AsyncValidator, AsyncValidatorFn, CheckboxControlValueAccessor, ControlContainer, ControlValueAccessor, DefaultValueAccessor, FormControl, NgControl, RadioControlValueAccessor, SelectControlValueAccessor, SelectMultipleControlValueAccessor, Validator, ValidatorFn, Validators } from '@angular/forms'; import { CrnkControl } from './crnk.expression.form.model.base'; import { ExpressionDefaultValueAccessorDirective } from './crnk.expression.form.model.accessor'; export function normalizeValidator(validator) { if (validator.validate) { return function (c) { return validator.validate(c); }; } else { return validator; } } export function normalizeAsyncValidator(validator) { if (validator.validate) { return function (c) { return validator.validate(c); }; } else { return validator; } } export function looseIdentical(a, b) { return a === b || typeof a === 'number' && typeof b === 'number' && isNaN(a) && isNaN(b); } export function isPresent(obj) { return obj !== null; } export function controlPath(name, parent) { return parent.path.concat([name]); } export function setUpControl(control, dir) { if (!control) { _throwError(dir, 'Cannot find control with'); } if (!dir.valueAccessor) { _throwError(dir, 'No value accessor for form control with'); } control.validator = Validators.compose([control.validator, dir.validator]); control.asyncValidator = Validators.composeAsync([control.asyncValidator, dir.asyncValidator]); dir.valueAccessor.writeValue(control.value); // view -> model dir.valueAccessor.registerOnChange(function (newValue) { dir.viewToModelUpdate(newValue); control.markAsDirty(); control.setValue(newValue, { emitModelToViewChange: false }); }); // touched dir.valueAccessor.registerOnTouched(function () { return control.markAsTouched(); }); control.registerOnChange(function (newValue, emitModelEvent) { // control -> view dir.valueAccessor.writeValue(newValue); // control -> ngModel if (emitModelEvent) { dir.viewToModelUpdate(newValue); } }); if (dir.valueAccessor.setDisabledState) { control.registerOnDisabledChange(function (isDisabled) { dir.valueAccessor.setDisabledState(isDisabled); }); } // re-run validation when validator binding changes, e.g. minlength=3 -> minlength=4 dir._rawValidators.forEach(function (validator) { if (validator.registerOnValidatorChange) { validator.registerOnValidatorChange(function () { return control.updateValueAndValidity(); }); } }); dir._rawAsyncValidators.forEach(function (validator) { if (validator.registerOnValidatorChange) { validator.registerOnValidatorChange(function () { return control.updateValueAndValidity(); }); } }); } function _noControlError(dir) { return _throwError(dir, 'There is no FormControl instance attached to form control element with'); } function _throwError(dir, message) { var messageEnd; if (dir.path.length > 1) { messageEnd = "path: '" + dir.path.join(' -> ') + "'"; } else if (dir.path[0]) { messageEnd = "name: '" + dir.path + "'"; } else { messageEnd = 'unspecified name attribute'; } throw new Error(message + " " + messageEnd); } export function composeValidators(validators) { return isPresent(validators) ? Validators.compose(validators.map(normalizeValidator)) : null; } export function composeAsyncValidators(validators) { return isPresent(validators) ? Validators.composeAsync(validators.map(normalizeAsyncValidator)) : null; } export function isPropertyUpdated(changes, viewModel) { if (!changes.hasOwnProperty('pathModel')) { return false; } var change = changes['pathModel']; if (change.isFirstChange()) { return true; } return !looseIdentical(viewModel, change.currentValue); } var BUILTIN_ACCESSORS = [ CheckboxControlValueAccessor, SelectControlValueAccessor, SelectMultipleControlValueAccessor, RadioControlValueAccessor, ]; export function isBuiltInAccessor(valueAccessor) { return BUILTIN_ACCESSORS.some(function (a) { return valueAccessor.constructor === a; }); } // TODO: vsavkin remove it once https://github.com/angular/angular/issues/3011 is implemented export function selectValueAccessor(dir, valueAccessors) { if (!valueAccessors) { return null; } var defaultAccessor; var builtinAccessor; var customAccessor; valueAccessors.forEach(function (v) { if (v.constructor === DefaultValueAccessor || v.constructor === ExpressionDefaultValueAccessorDirective) { defaultAccessor = v; } else if (isBuiltInAccessor(v)) { if (builtinAccessor) { _throwError(dir, 'More than one built-in value accessor matches form control with'); } builtinAccessor = v; } else { if (customAccessor) { _throwError(dir, 'More than one custom value accessor matches form control with'); } customAccessor = v; } }); if (customAccessor) { return customAccessor; } if (builtinAccessor) { return builtinAccessor; } if (defaultAccessor) { return defaultAccessor; } _throwError(dir, 'No valid value accessor for form control with'); return null; } var TemplateDrivenErrors = /** @class */ (function () { function TemplateDrivenErrors() { } TemplateDrivenErrors.modelParentException = function () { throw new Error("\n ngModel cannot be used to register form controls with a parent formGroup directive."); }; TemplateDrivenErrors.formGroupNameException = function () { throw new Error("\n ngModel cannot be used to register form controls with a parent formGroupName or formArrayName directive."); }; TemplateDrivenErrors.missingNameException = function () { throw new Error("If ngModel is used within a form tag, either the name attribute must be set or the form\n control must be defined as 'standalone' in ngModelOptions.\n Example 1: <input [(ngModel)]=\"person.firstName\" name=\"first\">\n Example 2: <input [(ngModel)]=\"person.firstName\" [ngModelOptions]=\"{standalone: true}\">"); }; TemplateDrivenErrors.modelGroupParentException = function () { throw new Error("\n ngModelGroup cannot be used with a parent formGroup directive."); }; return TemplateDrivenErrors; }()); export { TemplateDrivenErrors }; //# sourceMappingURL=crnk.expression.form.utils.js.map