Désactiver les champs de saisie sous forme réactive

118

J'ai déjà essayé de suivre l'exemple d'autres réponses d'ici et je n'ai pas réussi!

J'ai créé un formulaire réactif (c'est-à-dire dynamique) et je souhaite désactiver certains champs à tout moment. Mon code de formulaire:

this.form = this._fb.group({
  name: ['', Validators.required],
  options: this._fb.array([])
});

const control = <FormArray>this.form.controls['options'];
control.push(this._fb.group({
  value: ['']
}));

mon html:

<div class='row' formArrayName="options">
  <div *ngFor="let opt of form.controls.options.controls; let i=index">
    <div [formGroupName]="i">
      <select formArrayName="value">
        <option></option>
        <option>{{ opt.controls.value }}</option>
      </select>
    </div>
  </div>
</div>

J'ai réduit le code pour faciliter. Je souhaite désactiver le champ de type select. J'ai essayé de faire ce qui suit:

form = new FormGroup({
  first: new FormControl({value: '', disabled: true}, Validators.required),
});

Ca ne fonctionne pas! Quelqu'un a-t-il une suggestion?

Renato Souza de Oliveira
la source
Comment la sélection pourrait-elle être désactivée, lorsque vous essayez de désactiver un contrôle de formulaire appelé first? `:)
AJT82
C'était juste une faute de frappe. Je veux désactiver select. Pouvez-vous m'aider?
Renato Souza de Oliveira
Pourriez-vous reproduire un plunker?
AJT82
Essayez-vous de désactiver l'ensemble de la sélection? Et ce valuen'est pas un formArray, c'est un formControlName. Si vous voulez valueêtre un formArray, vous devrez le changer. Actuellement, il s'agit d'un formControlName. Donc, si vous voulez que tout le champ de sélection soit désactivé, <select formArrayName="value"><select formControlName="value">
passez

Réponses:

223
name: [{value: '', disabled: true}, Validators.required],
name: [{value: '', disabled: this.isDisabled}, Validators.required],

ou

this.form.controls['name'].disable();
Joche Wis
la source
si je mets une valeur comme ça -> country: [{value: this.address.country, disabled: true}] la valeur ne remplit pas
Silvio Troia
J'ai utilisé la même technique pour désactiver les champs qui ont été remplis automatiquement à partir de sources fiables. J'ai un commutateur pour activer / désactiver le formulaire, et après avoir activé tout le formulaire, je désactive généralement ces champs à l'aide d' ifinstructions. Une fois le formulaire soumis, tout le formulaire est à nouveau désactivé.
retr0
72

Faites attention

Si vous créez un formulaire en utilisant une variable pour condition et que vous essayez de le changer plus tard, cela ne fonctionnera pas, c'est -à- dire que le formulaire ne changera pas .

Par exemple

this.isDisabled = true;

this.cardForm = this.fb.group({
    'number': [{value: null, disabled: this.isDisabled},
});

et si vous changez la variable

this.isDisabled = false;

la forme ne changera pas. Tu devrais utiliser

this.cardForm.get ('nombre'). disable ();

BTW.

Vous devez utiliser la méthode patchValue pour changer la valeur:

this.cardForm.patchValue({
    'number': '1703'
});
Dmitry Grinko
la source
22

Il est déconseillé d'utiliser disable dans un DOM avec des formulaires réactifs. Vous pouvez définir cette option dans votre FormControl, lorsque vous lancez le depuis

username: new FormControl(
  {
    value: this.modelUser.Email,
    disabled: true
  },
  [
    Validators.required,
    Validators.minLength(3),
    Validators.maxLength(99)
  ]
);

La propriété valuen'est pas nécessaire

Ou vous pouvez obtenir votre contrôle de formulaire avec get('control_name')et définirdisable

this.userForm.get('username').disable();
Volodymyr Khmil
la source
Pourquoi est-ce une mauvaise pratique d'utiliser disable dans le DOM avec des formulaires réactifs?
pumpkinthehead le
2
Vous recevrez un avertissement d'angular. It looks like you’re using the disabled attribute with a reactive form directive. If you set disabled to true when you set up this control in your component class, the disabled attribute will actually be set in the DOM for you. We recommend using this approach to avoid ‘changed after checked’ errors. Donc, la méthode recommandée pour changer l'état de désactivation / activation directement via les commandes. Aussi, vous pouvez consulter ce grand sujet netbasal.com
Volodymyr Khmil
10

Je l'ai résolu en enveloppant mon objet d'entrée avec son étiquette dans un jeu de champs: le fieldset devrait avoir la propriété disabled liée au booléen

 <fieldset [disabled]="isAnonymous">
    <label class="control-label" for="firstName">FirstName</label>
    <input class="form-control" id="firstName" type="text" formControlName="firstName" />
 </fieldset>
Fernando M
la source
1
perdu beaucoup de temps à comprendre comment désactiver les contrôles sous des formes réactives, LOL! cela a fonctionné .. aucune directive ou code supplémentaire nécessaire. cheers 🍻
Nexus
7

Le disablingFormControl preventsdoit être présent dans un formulaire pendant saving. Vous pouvez simplement lui définir la readonlypropriété.

Et vous pouvez y parvenir de cette façon:

HTML:

<select formArrayName="value" [readonly] = "disableSelect">

TS:

this.disbaleSelect = true;

Trouvé ceci ici

Alex Po
la source
2
Vous pouvez utiliser form.getRawValue()pour inclure les valeurs des contrôles désactivés
Murhaf Sousli
6

Si vous souhaitez utiliser disableddes éléments d'entrée de formulaire (comme suggéré dans la réponse correcte, comment désactiver l'entrée ), la validation pour eux sera également désactivée, faites attention à cela!

(Et si vous utilisez le bouton Soumettre, [disabled]="!form.valid"cela exclura votre champ de la validation)

entrez la description de l'image ici

Alex Efimov
la source
1
Comment valider les champs initialement désactivés mais définis dynamiquement?
NeptuneOyster
5

Une approche plus générale serait.

// Variable/Flag declare
public formDisabled = false;

// Form init
this.form = new FormGroup({
  name: new FormControl({value: '', disabled: this.formDisabled}, 
    Validators.required),
 });

// Enable/disable form control
public toggleFormState() {
    this.formDisabled = !this.formDisabled;
    const state = this.formDisabled ? 'disable' : 'enable';

    Object.keys(this.form.controls).forEach((controlName) => {
        this.form.controls[controlName][state](); // disables/enables each form control based on 'this.formDisabled'
    });
}
Herbi Shtini
la source
3

Si vous souhaitez désactiver first(formcontrol), vous pouvez utiliser l'instruction ci-dessous.

this.form.first.disable();

Gampesh
la source
3

Cela a fonctionné pour moi: this.form.get('first').disable({onlySelf: true});

Foram Jhaveri
la source
3
this.form.enable()
this.form.disable()

Ou formcontrol 'first'

this.form.get('first').enable()
this.form.get('first').disable()

Vous pouvez définir désactiver ou activer sur la configuration initiale.

 first: new FormControl({disabled: true}, Validators.required)
Pu ChengLie
la source
2

entrez la description de l'image ici

lastName: new FormControl({value: '', disabled: true}, Validators.compose([Validators.required])),
Abdullah Pariyani
la source
1

La meilleure solution est ici:

https://netbasal.com/disabling-form-controls-when-working-with-reactive-forms-in-angular-549dd7b42110

Aperçu de la solution (en cas de lien rompu):

(1) Créer une directive

import { NgControl } from '@angular/forms';

@Directive({selector: '[disableControl]'})
export class DisableControlDirective {

  @Input() set disableControl( condition : boolean ) {
    const action = condition ? 'disable' : 'enable';
    this.ngControl.control[action]();
  }

  constructor( private ngControl : NgControl ) {}
}

(2) Utilisez-le comme ça

<input [formControl]="formControl" [disableControl]="condition">

(3) Étant donné que les entrées désactivées ne s'affichent pas dans form.value lors de la soumission, vous devrez peut-être utiliser les éléments suivants à la place (si nécessaire):

onSubmit(form) {
  const formValue = form.getRawValue() // gets form.value including disabled controls
  console.log(formValue)
}
danday74
la source
J'ai essayé de cette façon. J'affiche la plupart de mes FormControls après avoir extrait les données d'API, donc après avoir défini / corrigé la valeur de mon formControl en utilisant this.form.get('FIELD_NAME').patchValue(DYNAMIC_VALUE), j'affiche le formControl. quand il est passé à la directive, il montre Impossible de lire la propriété 'disable' de undefined
ImFarhad
0

J'ai eu le même problème, mais appeler this.form.controls ['name']. Disable () ne l'a pas résolu car je rechargeais ma vue (en utilisant router.navigate ()).

Dans mon cas, j'ai dû réinitialiser mon formulaire avant de recharger:

this.form = indéfini; this.router.navigate ([chemin]);

Tai Truong
la source
0
setTimeout(() => { emailGroup.disable(); });
Judson Terrell
la source
0

Vous pouvez déclarer une fonction pour activer / désactiver tout le contrôle de formulaire:

  toggleDisableFormControl(value: Boolean, exclude = []) {
    const state = value ? 'disable' : 'enable';
    Object.keys(this.profileForm.controls).forEach((controlName) => {
      if (!exclude.includes(controlName))
        this.profileForm.controls[controlName][state]();
    });
  }

et utilisez-le comme ça

this.toggleDisableFormControl(true, ['email']);
// disbale all field but email
Duong Le
la source
-2

Pour rendre un champ de désactivation et permettre de angulaire de forme réactive 2+

1. Pour désactiver

  • Ajoutez [attr.disabled] = "true" à l'entrée.

<input class="form-control" name="Firstname" formControlName="firstname" [attr.disabled]="true">

Autoriser

export class InformationSectionComponent {
formname = this.formbuilder.group({
firstname: ['']
});
}

Activer le formulaire entier

this.formname.enable();

Activer un champ particulier seul

this.formname.controls.firstname.enable();

idem pour disable, remplacez enable () par disable ().

Cela fonctionne très bien. Commentaire pour les requêtes.

Srinivasan N
la source