UNPKG

ngx-vest-forms

Version:

Opinionated template-driven forms library for Angular

70 lines 7.79 kB
import { Optional } from '@angular/core'; import { ControlContainer, FormsModule, NgForm, NgModelGroup, } from '@angular/forms'; import { ValidateRootFormDirective } from './directives/validate-root-form.directive'; import { ControlWrapperComponent } from './components/control-wrapper/control-wrapper.component'; import { FormDirective } from './directives/form.directive'; import { FormModelDirective } from './directives/form-model.directive'; import { FormModelGroupDirective } from './directives/form-model-group.directive'; /** * This is borrowed from [https://github.com/wardbell/ngc-validate/blob/main/src/app/core/form-container-view-provider.ts](https://github.com/wardbell/ngc-validate/blob/main/src/app/core/form-container-view-provider.ts) * Thank you so much Ward Bell for your effort!: * * Provide a ControlContainer to a form component from the * nearest parent NgModelGroup (preferred) or NgForm. * * Required for Reactive Forms as well (unless you write CVA) * * @example * ``` * @Component({ * ... * viewProviders[ formViewProvider ] * }) * ``` * @see Kara's AngularConnect 2017 talk: https://youtu.be/CD_t3m2WMM8?t=1826 * * Without this provider * - Controls are not registered with parent NgForm or NgModelGroup * - Form-level flags say "untouched" and "valid" * - No form-level validation roll-up * - Controls still validate, update model, and update their statuses * - If within NgForm, no compiler error because ControlContainer is optional for ngModel * * Note: if the SubForm Component that uses this Provider * is not within a Form or NgModelGroup, the provider returns `null` * resulting in an error, something like * ``` * preview-fef3604083950c709c52b.js:1 ERROR Error: * ngModelGroup cannot be used with a parent formGroup directive. *``` */ const formViewProvider = { provide: ControlContainer, useFactory: _formViewProviderFactory, deps: [ [new Optional(), NgForm], [new Optional(), NgModelGroup], ], }; function _formViewProviderFactory(ngForm, ngModelGroup) { return ngModelGroup || ngForm || null; } /** * The providers we need in every child component that holds an ngModelGroup */ export const vestFormsViewProviders = [ { provide: ControlContainer, useExisting: NgForm }, formViewProvider, // very important if we want nested components with ngModelGroup ]; /** * Exports all the stuff we need to use the template driven forms */ export const vestForms = [ ValidateRootFormDirective, ControlWrapperComponent, FormDirective, FormsModule, FormModelDirective, FormModelGroupDirective, ]; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhwb3J0cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL25neC12ZXN0LWZvcm1zL3NyYy9saWIvZXhwb3J0cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsUUFBUSxFQUFZLE1BQU0sZUFBZSxDQUFDO0FBQ25ELE9BQU8sRUFDTCxnQkFBZ0IsRUFDaEIsV0FBVyxFQUNYLE1BQU0sRUFDTixZQUFZLEdBQ2IsTUFBTSxnQkFBZ0IsQ0FBQztBQUN4QixPQUFPLEVBQUUseUJBQXlCLEVBQUUsTUFBTSwyQ0FBMkMsQ0FBQztBQUN0RixPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSx3REFBd0QsQ0FBQztBQUNqRyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDNUQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDdkUsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0seUNBQXlDLENBQUM7QUFFbEY7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBZ0NHO0FBQ0gsTUFBTSxnQkFBZ0IsR0FBYTtJQUNqQyxPQUFPLEVBQUUsZ0JBQWdCO0lBQ3pCLFVBQVUsRUFBRSx3QkFBd0I7SUFDcEMsSUFBSSxFQUFFO1FBQ0osQ0FBQyxJQUFJLFFBQVEsRUFBRSxFQUFFLE1BQU0sQ0FBQztRQUN4QixDQUFDLElBQUksUUFBUSxFQUFFLEVBQUUsWUFBWSxDQUFDO0tBQy9CO0NBQ0YsQ0FBQztBQUVGLFNBQVMsd0JBQXdCLENBQUMsTUFBYyxFQUFFLFlBQTBCO0lBQzFFLE9BQU8sWUFBWSxJQUFJLE1BQU0sSUFBSSxJQUFJLENBQUM7QUFDeEMsQ0FBQztBQUVEOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sc0JBQXNCLEdBQUc7SUFDcEMsRUFBRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsV0FBVyxFQUFFLE1BQU0sRUFBRTtJQUNsRCxnQkFBZ0IsRUFBRSxnRUFBZ0U7Q0FDbkYsQ0FBQztBQUVGOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sU0FBUyxHQUFHO0lBQ3ZCLHlCQUF5QjtJQUN6Qix1QkFBdUI7SUFDdkIsYUFBYTtJQUNiLFdBQVc7SUFDWCxrQkFBa0I7SUFDbEIsdUJBQXVCO0NBQ2YsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IE9wdGlvbmFsLCBQcm92aWRlciB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtcbiAgQ29udHJvbENvbnRhaW5lcixcbiAgRm9ybXNNb2R1bGUsXG4gIE5nRm9ybSxcbiAgTmdNb2RlbEdyb3VwLFxufSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBWYWxpZGF0ZVJvb3RGb3JtRGlyZWN0aXZlIH0gZnJvbSAnLi9kaXJlY3RpdmVzL3ZhbGlkYXRlLXJvb3QtZm9ybS5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgQ29udHJvbFdyYXBwZXJDb21wb25lbnQgfSBmcm9tICcuL2NvbXBvbmVudHMvY29udHJvbC13cmFwcGVyL2NvbnRyb2wtd3JhcHBlci5jb21wb25lbnQnO1xuaW1wb3J0IHsgRm9ybURpcmVjdGl2ZSB9IGZyb20gJy4vZGlyZWN0aXZlcy9mb3JtLmRpcmVjdGl2ZSc7XG5pbXBvcnQgeyBGb3JtTW9kZWxEaXJlY3RpdmUgfSBmcm9tICcuL2RpcmVjdGl2ZXMvZm9ybS1tb2RlbC5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgRm9ybU1vZGVsR3JvdXBEaXJlY3RpdmUgfSBmcm9tICcuL2RpcmVjdGl2ZXMvZm9ybS1tb2RlbC1ncm91cC5kaXJlY3RpdmUnO1xuXG4vKipcbiAqIFRoaXMgaXMgYm9ycm93ZWQgZnJvbSAgW2h0dHBzOi8vZ2l0aHViLmNvbS93YXJkYmVsbC9uZ2MtdmFsaWRhdGUvYmxvYi9tYWluL3NyYy9hcHAvY29yZS9mb3JtLWNvbnRhaW5lci12aWV3LXByb3ZpZGVyLnRzXShodHRwczovL2dpdGh1Yi5jb20vd2FyZGJlbGwvbmdjLXZhbGlkYXRlL2Jsb2IvbWFpbi9zcmMvYXBwL2NvcmUvZm9ybS1jb250YWluZXItdmlldy1wcm92aWRlci50cylcbiAqIFRoYW5rIHlvdSBzbyBtdWNoIFdhcmQgQmVsbCBmb3IgeW91ciBlZmZvcnQhOlxuICpcbiAqIFByb3ZpZGUgYSBDb250cm9sQ29udGFpbmVyIHRvIGEgZm9ybSBjb21wb25lbnQgZnJvbSB0aGVcbiAqIG5lYXJlc3QgcGFyZW50IE5nTW9kZWxHcm91cCAocHJlZmVycmVkKSBvciBOZ0Zvcm0uXG4gKlxuICogUmVxdWlyZWQgZm9yIFJlYWN0aXZlIEZvcm1zIGFzIHdlbGwgKHVubGVzcyB5b3Ugd3JpdGUgQ1ZBKVxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGBcbiAqICAgQENvbXBvbmVudCh7XG4gKiAgICAgLi4uXG4gKiAgICB2aWV3UHJvdmlkZXJzWyBmb3JtVmlld1Byb3ZpZGVyIF1cbiAqICAgfSlcbiAqIGBgYFxuICogQHNlZSBLYXJhJ3MgQW5ndWxhckNvbm5lY3QgMjAxNyB0YWxrOiBodHRwczovL3lvdXR1LmJlL0NEX3QzbTJXTU04P3Q9MTgyNlxuICpcbiAqIFdpdGhvdXQgdGhpcyBwcm92aWRlclxuICogLSBDb250cm9scyBhcmUgbm90IHJlZ2lzdGVyZWQgd2l0aCBwYXJlbnQgTmdGb3JtIG9yIE5nTW9kZWxHcm91cFxuICogLSBGb3JtLWxldmVsIGZsYWdzIHNheSBcInVudG91Y2hlZFwiIGFuZCBcInZhbGlkXCJcbiAqIC0gTm8gZm9ybS1sZXZlbCB2YWxpZGF0aW9uIHJvbGwtdXBcbiAqIC0gQ29udHJvbHMgc3RpbGwgdmFsaWRhdGUsIHVwZGF0ZSBtb2RlbCwgYW5kIHVwZGF0ZSB0aGVpciBzdGF0dXNlc1xuICogLSBJZiB3aXRoaW4gTmdGb3JtLCBubyBjb21waWxlciBlcnJvciBiZWNhdXNlIENvbnRyb2xDb250YWluZXIgaXMgb3B0aW9uYWwgZm9yIG5nTW9kZWxcbiAqXG4gKiBOb3RlOiBpZiB0aGUgU3ViRm9ybSBDb21wb25lbnQgdGhhdCB1c2VzIHRoaXMgUHJvdmlkZXJcbiAqIGlzIG5vdCB3aXRoaW4gYSBGb3JtIG9yIE5nTW9kZWxHcm91cCwgdGhlIHByb3ZpZGVyIHJldHVybnMgYG51bGxgXG4gKiByZXN1bHRpbmcgaW4gYW4gZXJyb3IsIHNvbWV0aGluZyBsaWtlXG4gKiBgYGBcbiAqIHByZXZpZXctZmVmMzYwNDA4Mzk1MGM3MDljNTJiLmpzOjEgRVJST1IgRXJyb3I6XG4gKiAgbmdNb2RlbEdyb3VwIGNhbm5vdCBiZSB1c2VkIHdpdGggYSBwYXJlbnQgZm9ybUdyb3VwIGRpcmVjdGl2ZS5cbiAqYGBgXG4gKi9cbmNvbnN0IGZvcm1WaWV3UHJvdmlkZXI6IFByb3ZpZGVyID0ge1xuICBwcm92aWRlOiBDb250cm9sQ29udGFpbmVyLFxuICB1c2VGYWN0b3J5OiBfZm9ybVZpZXdQcm92aWRlckZhY3RvcnksXG4gIGRlcHM6IFtcbiAgICBbbmV3IE9wdGlvbmFsKCksIE5nRm9ybV0sXG4gICAgW25ldyBPcHRpb25hbCgpLCBOZ01vZGVsR3JvdXBdLFxuICBdLFxufTtcblxuZnVuY3Rpb24gX2Zvcm1WaWV3UHJvdmlkZXJGYWN0b3J5KG5nRm9ybTogTmdGb3JtLCBuZ01vZGVsR3JvdXA6IE5nTW9kZWxHcm91cCkge1xuICByZXR1cm4gbmdNb2RlbEdyb3VwIHx8IG5nRm9ybSB8fCBudWxsO1xufVxuXG4vKipcbiAqIFRoZSBwcm92aWRlcnMgd2UgbmVlZCBpbiBldmVyeSBjaGlsZCBjb21wb25lbnQgdGhhdCBob2xkcyBhbiBuZ01vZGVsR3JvdXBcbiAqL1xuZXhwb3J0IGNvbnN0IHZlc3RGb3Jtc1ZpZXdQcm92aWRlcnMgPSBbXG4gIHsgcHJvdmlkZTogQ29udHJvbENvbnRhaW5lciwgdXNlRXhpc3Rpbmc6IE5nRm9ybSB9LFxuICBmb3JtVmlld1Byb3ZpZGVyLCAvLyB2ZXJ5IGltcG9ydGFudCBpZiB3ZSB3YW50IG5lc3RlZCBjb21wb25lbnRzIHdpdGggbmdNb2RlbEdyb3VwXG5dO1xuXG4vKipcbiAqIEV4cG9ydHMgYWxsIHRoZSBzdHVmZiB3ZSBuZWVkIHRvIHVzZSB0aGUgdGVtcGxhdGUgZHJpdmVuIGZvcm1zXG4gKi9cbmV4cG9ydCBjb25zdCB2ZXN0Rm9ybXMgPSBbXG4gIFZhbGlkYXRlUm9vdEZvcm1EaXJlY3RpdmUsXG4gIENvbnRyb2xXcmFwcGVyQ29tcG9uZW50LFxuICBGb3JtRGlyZWN0aXZlLFxuICBGb3Jtc01vZHVsZSxcbiAgRm9ybU1vZGVsRGlyZWN0aXZlLFxuICBGb3JtTW9kZWxHcm91cERpcmVjdGl2ZSxcbl0gYXMgY29uc3Q7XG4iXX0=