Core package of ngx-formly - a dynamic (JSON powered) form library for Angular that brings unmatched maintainability to your application's forms
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Core services for configuration management, form building, and dynamic field generation in NGX-Formly.
Injectable service for managing global Formly configuration including field types, validators, wrappers, and extensions.
/**
* Service for managing global Formly configuration
*/
@Injectable({ providedIn: 'root' })
export class FormlyConfig {
/** Extra configuration options */
extras: FormlyConfigExtras;
/**
* Add configuration options to the global configuration
* @param config - Configuration options to add
*/
addConfig(config: ConfigOption): void;
/**
* Register field type(s) with the configuration system
* @param options - Field type configuration or array of configurations
*/
setType(options: TypeOption | TypeOption[]): void;
/**
* Register wrapper(s) with the configuration system
* @param options - Wrapper configuration or array of configurations
*/
setWrapper(options: WrapperOption | WrapperOption[]): void;
/**
* Register validator(s) with the configuration system
* @param options - Validator configuration or array of configurations
*/
setValidator(options: ValidatorOption | ValidatorOption[]): void;
/**
* Register validation message(s) with the configuration system
* @param options - Validation message configuration or array of configurations
*/
setValidationMessage(options: ValidationMessageOption | ValidationMessageOption[]): void;
/**
* Get field type configuration by name
* @param name - Name of the field type or component type
* @param throwIfNotFound - Whether to throw error if type not found
* @returns Field type configuration
*/
getType(name: FormlyFieldConfig['type'], throwIfNotFound?: boolean): TypeOption;
/**
* Get validator configuration by name
* @param name - Name of the validator
* @returns Validator configuration
*/
getValidator(name: string): ValidatorOption;
/**
* Get wrapper configuration by name
* @param name - Name of the wrapper or wrapper component type
* @returns Wrapper configuration
*/
getWrapper(name: string | Type<FieldWrapper>): WrapperOption;
/**
* Add validation message for a specific validator
* @param name - Name of the validator
* @param message - Message string or function
*/
addValidatorMessage(name: string, message: ValidationMessageOption['message']): void;
/**
* Get validation message by validator name
* @param name - Name of the validator
* @returns Validation message
*/
getValidatorMessage(name: string): ValidationMessageOption['message'];
/** Map of registered field types */
types: { [name: string]: TypeOption };
/** Map of registered validators */
validators: { [name: string]: ValidatorOption };
/** Map of registered wrappers */
wrappers: { [name: string]: WrapperOption };
/** Map of registered validation messages */
messages: { [name: string]: ValidationMessageOption['message'] };
/** Map of registered extensions */
extensions: { [name: string]: FormlyExtension };
}Usage Example:
import { Injectable, Component } from '@angular/core';
import { FormlyConfig, FieldType } from '@ngx-formly/core';
@Component({
selector: 'custom-input',
template: `<input [formControl]="formControl" [formlyAttributes]="field">`
})
export class CustomInputComponent extends FieldType {}
@Injectable()
export class MyConfigService {
constructor(private formlyConfig: FormlyConfig) {
this.setupConfiguration();
}
private setupConfiguration() {
// Register custom field type
this.formlyConfig.setType({
name: 'custom-input',
component: CustomInputComponent,
wrappers: ['form-field']
});
// Register custom validator
this.formlyConfig.setValidator({
name: 'custom-validator',
validation: (control) => {
return control.value && control.value.length > 5 ? null : { customValidator: true };
}
});
// Register validation message
this.formlyConfig.setValidationMessage({
name: 'custom-validator',
message: 'This field must be longer than 5 characters'
});
}
}Injectable service for building and managing form structures from field configurations.
/**
* Service for building forms from field configurations
*/
@Injectable({ providedIn: 'root' })
export class FormlyFormBuilder {
/**
* Build form controls and structure from field configurations
* @param form - The Angular FormGroup or UntypedFormGroup to build into
* @param fields - Array of field configurations
* @param model - The data model to bind to
* @param options - Form options and lifecycle hooks
*/
/**
* Build and configure form controls for field configurations
* @param field - Field configuration to build
* @returns Processed field configuration
*/
build(field: FormlyFieldConfigCache): FormlyFieldConfigCache;
}Usage Example:
import { Component, OnInit } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { FormlyFormBuilder, FormlyFieldConfig, FormlyFormOptions } from '@ngx-formly/core';
@Component({
selector: 'app-dynamic-form',
template: `
<form [formGroup]="form">
<formly-form [form]="form" [fields]="fields" [model]="model" [options]="options">
</formly-form>
</form>
`
})
export class DynamicFormComponent implements OnInit {
form = new FormGroup({});
model = {};
fields: FormlyFieldConfig[] = [];
options: FormlyFormOptions = {};
constructor(private formBuilder: FormlyFormBuilder) {}
ngOnInit() {
this.fields = [
{
key: 'firstName',
type: 'input',
props: { label: 'First Name', required: true }
},
{
key: 'lastName',
type: 'input',
props: { label: 'Last Name', required: true }
}
];
// Manually build the form (usually done automatically by FormlyForm component)
this.formBuilder.buildForm(this.form, this.fields, this.model, this.options);
}
}interface FormlyConfigExtras {
/** Whether to check expressions on form initialization */
checkExpressionOn?: 'modelChange' | 'changeDetectionCheck';
/** Whether to immediately render extensions */
immutable?: boolean;
/** Whether to show errors immediately */
showError?: (field: FormlyFieldConfig) => boolean;
/** Custom error state matcher */
errorStateMatcher?: ErrorStateMatcher;
/** Field transform function */
fieldTransform?: (
fields: FormlyFieldConfig[],
model: any,
form: FormGroup | UntypedFormGroup,
options: FormlyFormOptions
) => FormlyFieldConfig[];
/** Whether to reset field values when hidden */
resetFieldOnHide?: boolean;
/** Whether to render fields when hidden */
renderFormlyFieldElement?: boolean;
/** Whether to remove form control when field is hidden */
removeFormControlOnHide?: boolean;
/** Class name to add to formly-field elements */
formlyFieldElementClassName?: string;
/** Whether to use legacy API */
useLegacyAPI?: boolean;
}
interface ErrorStateMatcher {
/**
* Determine if field should show error state
* @param control - The form control
* @param form - The parent form
* @returns True if error should be shown
*/
isErrorState(control: AbstractControl | null, form: FormGroupDirective | NgForm | null): boolean;
}interface FormlyFormOptions {
/** Shared state object accessible to all fields */
formState?: any;
/** Subject for listening to field value changes */
fieldChanges?: Subject<FormlyValueChangeEvent>;
/** Function to transform fields before rendering */
fieldTransform?: (
fields: FormlyFieldConfig[],
model: any,
form: FormGroup | UntypedFormGroup,
options: FormlyFormOptions
) => FormlyFieldConfig[];
/** Custom function to determine when to show field errors */
showError?: (field: FormlyFieldConfig) => boolean;
/** Whether to reset field values when fields are hidden */
resetOnHide?: boolean;
/** Parent form directive for nested forms */
parentForm?: FormGroupDirective | null;
/** Function to update initial values */
updateInitialValue?: () => void;
/** Function to check field expressions */
checkExpressions?: (field: FormlyFieldConfig, ignoreCache?: boolean) => void;
/** Function to trigger change detection */
detectChanges?: (field: FormlyFieldConfig) => void;
/** Function to build field configurations */
build?: (field?: FormlyFieldConfig) => FormlyFieldConfig[];
// Internal properties
_resolver?: ComponentFactoryResolver;
_viewContainerRef?: ViewContainerRef;
_markForCheck?: (field: FormlyFieldConfig) => void;
_hiddenFieldsForCheck?: FormlyFieldConfig[];
_initialModel?: any;
}
interface FormlyValueChangeEvent {
/** The field that triggered the change */
field: FormlyFieldConfig;
/** The field type that changed */
type: string;
/** The new value */
value: any;
}