Disabilita i campi di input in forma reattiva


118

Ho già provato a seguire l'esempio di altre risposte da qui e non ci sono riuscito!

Ho creato un modulo reattivo (cioè dinamico) e desidero disabilitare alcuni campi in un dato momento. Il mio codice modulo:

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: ['']
}));

il mio 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>

Ho ridotto il codice per facilitare. Voglio disabilitare il campo di selezione del tipo. Ho provato a fare quanto segue:

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

non funziona! Qualcuno ha un suggerimento?


Come potrebbe essere disabilitata la selezione, quando si tenta di disabilitare un controllo del modulo chiamato first? `:)
AJT82

Era solo un errore di battitura. Voglio disabilitare la selezione. Mi potete aiutare?
Renato Souza de Oliveira

Potresti riprodurre un plunker?
AJT82

Stai cercando di disabilitare l'intera selezione? E valuenon è un formArray, è un formControlName. Se vuoi valueessere un formArray dovresti cambiarlo. Attualmente è un formControlName. Quindi, se vuoi disabilitare l'intero campo di selezione, cambia semplicemente <select formArrayName="value">in<select formControlName="value">
AJT82

Risposte:


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

o

this.form.controls['name'].disable();

se imposto un valore del genere -> country: [{value: this.address.country, disabled: true}] il valore non riempire
Silvio Troia

Ho utilizzato la stessa tecnica per disabilitare i campi compilati automaticamente da fonti attendibili. Ho un interruttore per abilitare / disabilitare il modulo e, dopo aver abilitato l'intero modulo, di solito disabilito quei campi usando le ifistruzioni. Dopo che il modulo è stato inviato, l'intero modulo viene nuovamente disabilitato.
retro0

72

Fai attenzione

Se stai creando un form usando una variabile per condition e provando a cambiarlo in seguito, non funzionerà, cioè il form non cambierà .

Per esempio

this.isDisabled = true;

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

e se cambi la variabile

this.isDisabled = false;

il modulo non cambierà. Dovresti usare

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

BTW.

È necessario utilizzare il metodo patchValue per modificare il valore:

this.cardForm.patchValue({
    'number': '1703'
});

22

È una cattiva pratica usare disable in un DOM con moduli reattivi. Puoi impostare questa opzione nel tuo FormControl, quando inizi da

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

La proprietà valuenon è necessaria

Oppure puoi ottenere il controllo del modulo con get('control_name')e impostaredisable

this.userForm.get('username').disable();

Perché è una cattiva pratica usare disable nel DOM con moduli reattivi?
Pumpkinthehead

2
Riceverai un avviso da angolare. 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. Quindi il modo consigliato per modificare lo stato di disabilitazione / abilitazione direttamente tramite i controlli. Inoltre, puoi controllare questo fantastico argomento netbasal.com/…
Volodymyr Khmil

10

L'ho risolto avvolgendo il mio oggetto di input con la sua etichetta in un set di campi: Il fieldset dovrebbe avere la proprietà disabilitata associata al booleano

 <fieldset [disabled]="isAnonymous">
    <label class="control-label" for="firstName">FirstName</label>
    <input class="form-control" id="firstName" type="text" formControlName="firstName" />
 </fieldset>

1
perso un sacco di tempo a capire come disabilitare i controlli in forme reattive, LOL! questo ha funzionato .. nessuna direttiva o codice aggiuntivo necessario. saluti 🍻
Nexus

7

Il disablingFormControl preventsdeve essere presente in un modulo while saving. Puoi semplicemente impostare il filereadonly proprietà.

E puoi ottenerlo in questo modo:

HTML:

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

TS:

this.disbaleSelect = true;

Trovato questo qui


2
È possibile utilizzare form.getRawValue()per includere i valori dei controlli disabilitati
Murhaf Sousli

6

Se per utilizzare gli disabledelementi di input del modulo (come suggerito nella risposta corretta come disabilitare l'input ) anche la convalida per loro sarà disabilitata, fai attenzione!

(E se stai usando il pulsante di invio come [disabled]="!form.valid"questo escluderà il tuo campo dalla convalida)

inserisci qui la descrizione dell'immagine


1
Come puoi convalidare i campi che sono inizialmente disabilitati ma sono impostati dinamicamente?
NeptuneOyster

5

Sarebbe un approccio più generale.

// 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'
    });
}

3

Se si desidera disabilitare first(formcontrol), è possibile utilizzare l'istruzione seguente.

this.form.first.disable();


3

Questo ha funzionato per me: this.form.get('first').disable({onlySelf: true});


3
this.form.enable()
this.form.disable()

Oppure formcontrol 'first'

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

È possibile impostare disabilitare o abilitare sul set iniziale.

 first: new FormControl({disabled: true}, Validators.required)

2

inserisci qui la descrizione dell'immagine

lastName: new FormControl({value: '', disabled: true}, Validators.compose([Validators.required])),

1

La soluzione migliore è qui:

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

Schema della soluzione (in caso di collegamento interrotto):

(1) Crea una direttiva

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) Usalo in questo modo

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

(3) Poiché gli input disabilitati non vengono visualizzati in form.value al momento dell'invio, potrebbe essere necessario utilizzare quanto segue (se richiesto):

onSubmit(form) {
  const formValue = form.getRawValue() // gets form.value including disabled controls
  console.log(formValue)
}

Ho provato in questo modo. Sto mostrando la maggior parte dei miei FormControls dopo aver estratto i dati API, quindi dopo aver impostato / applicato il valore al mio formControl usando this.form.get('FIELD_NAME').patchValue(DYNAMIC_VALUE)formControl. quando è passato alla direttiva, mostra Impossibile leggere la proprietà 'disable' di undefined
ImFarhad

0

Ho avuto lo stesso problema, ma chiamando this.form.controls ['name']. Disable () non l'ho risolto perché stavo ricaricando la mia vista (usando router.navigate ()).

Nel mio caso ho dovuto resettare il mio modulo prima di ricaricarlo:

this.form = undefined; this.router.navigate ([percorso]);



0

È possibile dichiarare una funzione per abilitare / disabilitare tutto il controllo del modulo:

  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]();
    });
  }

e usalo in questo modo

this.toggleDisableFormControl(true, ['email']);
// disbale all field but email

-2

Per disabilitare e abilitare un campo della forma reattiva angolare 2+

1. Per disabilitare

  • Aggiungi [attr.disabled] = "true" all'input.

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

Abilitare

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

Abilita modulo intero

this.formname.enable();

Abilita solo un campo particolare

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

lo stesso per disable, sostituire enable () con disable ().

Funziona bene. Commento per le domande.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.