
Simplifier, structurer et maintenir vos formulaires Angular
Code:

Réduire la duplication, améliorer la lisibilité et faciliter la maintenance des formulaires complexes.
Création originale sous angular-formly 1.0.0 en 2014
Reprise et adaptation pour Angular moderne
Maintenu par la communauté avec plusieurs dizaines de milliers de téléchargements hebdomadaires sur npm
Configuration décrivant la structure des champs, leurs validations, conditions d’affichage et interactions.
FormlyInterprète la configuration pour créer automatiquement les composants de formulaire Angular.
Liaison automatique entre les champs du formulaire et le modèle de données, avec validation intégrée.
➡️ Toute la logique de rendu, de validation et d'affichage est déléguée au composant <formly-form>.
fields: FormlyFieldConfig[] = [
{
key: 'firstName',
type: 'input',
props: {
label: 'Prénom',
required: true,
minLength: 2,
},
validation: {
messages: {
required: 'Le prénom est obligatoire',
minlength: 'Le prénom doit contenir au moins 2 caractères',
},
},
},
];
➡️ Ce bloc suffit à générer un champ réactif complet, avec validation, label, et messages d’erreur automatiques.
fields: FormlyFieldConfig[] = [
{
key: 'country',
type: 'select',
props: {
label: 'Pays',
required: true,
options: [
{ label: 'France', value: 'FR' },
{ label: 'Belgique', value: 'BE' },
{ label: 'Suisse', value: 'CH' },
],
},
},
];
➡️ Un menu déroulant simple où Formly gère le rendu des balises <option> automatiquement.
fields: FormlyFieldConfig[] = [
{
key: 'city',
type: 'select',
props: {
label: 'Ville',
options: this.cityService.getCities(), // Observable<{label, value}[]>
valueProp: 'id',
labelProp: 'name',
},
},
];
➡️ Formly gère nativement les Observables pour charger les données depuis une API, et vous permet de mapper facilement les clés avec valueProp et labelProp.
fields: FormlyFieldConfig[] = [
{
key: 'isCompany',
type: 'checkbox',
props: {
label: 'Est-ce une société ?',
},
},
{
key: 'companyName',
type: 'input',
props: {
label: 'Nom de la société',
required: true,
},
hideExpression: '!model.isCompany', // ou 'hide: !model.isCompany'
},
];
➡️ Le champ Nom de la société n’apparaît que si la case Est-ce une société ? est cochée. Formly gère automatiquement l’affichage conditionnel et les validations dynamiques.
fields: FormlyFieldConfig[] = [
{
key: 'email',
type: 'input',
props: { label: 'Email' },
hooks: {
onInit: (field) => {
field.formControl.valueChanges.subscribe(v => {
console.log('Email a changé :', v);
});
},
},
},
];
➡️ Interagissez directement avec le FormControl généré grâce aux hooks (onInit, onChanges, onDestroy...) pour des comportements spécifiques complexes.
this.form = this.fb.group({
isCompany: [false],
companyName: [''],
});
this.form.get('isCompany')?.valueChanges.subscribe((isCompany) => {
const companyNameControl = this.form.get('companyName');
if (isCompany) {
companyNameControl?.setValidators([Validators.required]);
} else {
companyNameControl?.clearValidators();
companyNameControl?.setValue('');
}
companyNameControl?.updateValueAndValidity();
});
➡️ Le champ Nom de la société n’apparaît que si la case Est-ce une société ? est cochée. Ici, l’affichage conditionnel et la validation sont gérés manuellement via les Reactive Forms d’Angular (avec un *ngIf et des Validators dynamiques).
Aller au-delà des types de champs par défaut.
Créez votre propre composant Angular (ex: <app-slider>), étendez FieldType, et déclarez-le dans le module Formly.
Entourez vos champs avec du HTML personnalisé (panels, cards, tooltips) sans modifier le champ lui-même.
// 1. Le composant Angular
@Component({
selector: 'formly-field-custom-input',
template: `
Erreur personnalisée
`,
})
export class CustomInputComponent extends FieldType<FieldTypeConfig> {}
// 2. Utilisation
{ key: 'myField', type: 'custom-input', props: { label: 'Mon Champ' } }
// 1. Le composant Angular (Wrapper)
@Component({
selector: 'formly-wrapper-panel',
template: `
{{ props.label }}
`,
})
export class PanelWrapperComponent extends FieldWrapper {}
// 2. Utilisation
{
key: 'myField',
type: 'input',
wrappers: ['panel'],
props: { label: 'Mon Champ avec Panel' }
}
fields: FormlyFieldConfig[] = [
{
key: 'amount',
type: 'input',
props: { type: 'number' },
},
{
key: 'message',
type: 'input',
expressionProperties: {
// Le label change selon la valeur de 'amount'
'props.label': 'model.amount > 100 ? "Montant élevé" : "Montant normal"',
// Désactivé si 'amount' est vide ou <= 0
'props.disabled': '!model.amount || model.amount <= 0',
// Ajout de classe dynamique
'props.className': 'model.amount > 1000 ? "text-red-500" : ""'
}
},
];
➡️ expressionProperties permet d'évaluer dynamiquement presque n'importe quelle propriété du champ en fonction du model ou du formState.
Formly simplifie la création de formulaires Angular : moins de code, maintenance simplifiée et réutilisation maximale. Voici un aperçu clair de ses points forts et des quelques limites à connaître.

