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?


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

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

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

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>

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


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


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

3

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

this.form.first.disable();



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)


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)
}

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



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

-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ń.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.