Wyłącz pola wejściowe w formularzu reaktywnym

118

Próbowałem już pójść za przykładem innych odpowiedzi stąd i nie udało mi się!

Utworzyłem formularz reaktywny (tj. Dynamiczny) i chcę w dowolnym momencie wyłączyć niektóre pola. Mój kod formularza:

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

mój 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>

Skróciłem kod, aby ułatwić. Chcę wyłączyć pole wyboru typu. Próbowałem wykonać następujące czynności:

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

nie działa! Ktokolwiek ma jakieś sugestie?

Renato Souza de Oliveira
źródło
Jak można wyłączyć zaznaczanie, gdy próbujesz wyłączyć jakąś kontrolkę formularza o nazwie first? `:)
AJT82
To była tylko literówka. Chcę wyłączyć zaznaczanie. Możesz mi pomóc?
Renato Souza de Oliveira
Czy mógłbyś odtworzyć plunkra?
AJT82
Czy próbujesz wyłączyć cały wybór? I valuenie jest formArray, to formControlName. Jeśli chcesz valuebyć formArray, musisz to zmienić. Obecnie jest to formControlName. Więc jeśli chcesz, aby całe pole wyboru zostało wyłączone, po prostu zmień <select formArrayName="value">na<select formControlName="value">
AJT82

Odpowiedzi:

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

lub

this.form.controls['name'].disable();
Joche Wis
źródło
jeśli ustawię taką wartość -> country: [{value: this.address.country, disabled: true}], wartość nie jest wypełniona
Silvio Troia
Użyłem tej samej techniki, aby wyłączyć pola, które zostały automatycznie wypełnione z zaufanych źródeł. Mam przełącznik do włączania / wyłączania formularza, a po włączeniu całego formularza zazwyczaj wyłączam te pola za pomocą ifinstrukcji. Po przesłaniu formularza cały formularz jest ponownie wyłączany.
retr0
72

Zwróć uwagę

Jeśli tworzysz formularz używając zmiennej warunku i próbujesz go później zmienić, to nie zadziała, tj . Forma się nie zmieni .

Na przykład

this.isDisabled = true;

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

i jeśli zmienisz zmienną

this.isDisabled = false;

forma nie ulegnie zmianie. Powinieneś użyć

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

BTW.

Do zmiany wartości należy użyć metody patchValue:

this.cardForm.patchValue({
    'number': '1703'
});
Dmitry Grinko
źródło
22

Używanie wyłączania w DOM z formularzami reaktywnymi jest złą praktyką. Możesz ustawić tę opcję w swoim FormControl, podczas inicjowania pliku from

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

Nieruchomość valuenie jest konieczna

Lub możesz uzyskać kontrolę nad formularzem za pomocą get('control_name')i ustawićdisable

this.userForm.get('username').disable();
Volodymyr Khmil
źródło
Dlaczego używanie wyłączania w DOM z formularzami reaktywnymi jest złą praktyką?
pumpkinthehead
2
Otrzymasz ostrzeżenie od angulara. 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. Dlatego zalecany sposób zmiany stanu wyłączenia / włączenia bezpośrednio za pomocą elementów sterujących. Możesz również sprawdzić ten wspaniały temat netbasal.com/…
Volodymyr Khmil
10

Rozwiązałem to, owijając mój obiekt wejściowy etykietą w zestawie pól: Zestaw pól powinien mieć właściwość disabled powiązaną z wartością logiczną

 <fieldset [disabled]="isAnonymous">
    <label class="control-label" for="firstName">FirstName</label>
    <input class="form-control" id="firstName" type="text" formControlName="firstName" />
 </fieldset>
Fernando M
źródło
1
zmarnowałem dużo czasu, zastanawiając się, jak wyłączyć kontrolki w formularzach reaktywnych, LOL! to zadziałało… nie potrzeba żadnych dyrektyw ani dodatkowego kodu. okrzyki 🍻
Nexus
7

disablingFormControl prevents, że jest obecny w postaci while saving. Możesz po prostu ustawić readonlywłaściwość.

Możesz to osiągnąć w ten sposób:

HTML:

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

TS:

this.disbaleSelect = true;

Znalazłem to tutaj

Alex Po
źródło
2
Możesz użyć, form.getRawValue()aby dołączyć wyłączone wartości kontrolne
Murhaf Sousli
6

Jeśli użyć disabledelementów wejściowych formularza (jak sugerowano w poprawnej odpowiedzi, jak wyłączyć wprowadzanie ), ich walidacja również zostanie wyłączona, zwróć na to uwagę!

(A jeśli używasz przycisku przesyłania, [disabled]="!form.valid"co spowoduje wykluczenie pola z walidacji)

wprowadź opis obrazu tutaj

Alex Efimov
źródło
1
Jak sprawdzić poprawność pól, które są początkowo wyłączone, ale są ustawiane dynamicznie?
NeptuneOyster
5

Byłoby bardziej ogólne podejście.

// 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
źródło
3

Jeśli chcesz wyłączyć first(formcontrol), możesz użyć poniższej instrukcji.

this.form.first.disable();

Gampesh
źródło
3

To zadziałało dla mnie: this.form.get('first').disable({onlySelf: true});

Foram Jhaveri
źródło
3
this.form.enable()
this.form.disable()

Lub formcontrol „pierwszy”

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

Możesz wyłączyć lub włączyć na początkowym ustawieniu.

 first: new FormControl({disabled: true}, Validators.required)
Pu ChengLie
źródło
2

wprowadź opis obrazu tutaj

lastName: new FormControl({value: '', disabled: true}, Validators.compose([Validators.required])),
Abdullah Pariyani
źródło
1

Najlepsze rozwiązanie jest tutaj:

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

Zarys rozwiązania (w przypadku niedziałającego linku):

(1) Utwórz dyrektywę

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) Używaj go w ten sposób

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

(3) Ponieważ wyłączone dane wejściowe nie są wyświetlane w form.value podczas przesyłania, może być konieczne użycie następujących zamiast tego (jeśli jest to wymagane):

onSubmit(form) {
  const formValue = form.getRawValue() // gets form.value including disabled controls
  console.log(formValue)
}
danday74
źródło
Próbowałem w ten sposób. Po ściągnięciu danych API pokazuję większość moich FormControls, więc po ustawieniu / poprawieniu wartości do mojego formControl za pomocą this.form.get('FIELD_NAME').patchValue(DYNAMIC_VALUE)pokazuję formControl. kiedy przeszedł do dyrektywy, pokazuje Cannot read property 'disable' of undefined
ImFarhad
0

Miałem ten sam problem, ale wywołanie this.form.controls ['name']. Disable () nie rozwiązało problemu, ponieważ ładowałem ponownie widok (używając router.navigate ()).

W moim przypadku musiałem zresetować mój formularz przed ponownym załadowaniem:

this.form = undefined; this.router.navigate ([ścieżka]);

Tai Truong
źródło
0
setTimeout(() => { emailGroup.disable(); });
Judson Terrell
źródło
0

Możesz zadeklarować funkcję, aby włączyć / wyłączyć całą kontrolkę formularza:

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

i używaj go w ten sposób

this.toggleDisableFormControl(true, ['email']);
// disbale all field but email
Duong Le
źródło
-2

Aby dokonać pole Wyłącz i pozwalają na postaci reaktywnej kątowego 2+

1. Aby wyłączyć

  • Dodaj [attr.disabled] = "true" do wejścia.

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

Umożliwić

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

Włącz cały formularz

this.formname.enable();

Włącz tylko określone pole

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

to samo dla disable, zamień enable () na disable ().

To działa dobrze. Komentarz do zapytań.

Srinivasan N
źródło