ngx-vest-forms
Version:
Opinionated template-driven forms library for Angular
70 lines • 7.79 kB
JavaScript
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=