Desativar campos de entrada na forma reativa

118

Já tentei seguir o exemplo de outras respostas daqui e não consegui!

Criei um formulário reativo (ou seja, dinâmico) e quero desabilitar alguns campos a qualquer momento. Meu código de formulário:

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

meu 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>

Reduzi o código para facilitar. Quero desativar o campo de seleção de tipo. Tentei fazer o seguinte:

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

não está funcionando! Alguém tem uma sugestão?

Renato Souza de Oliveira
fonte
Como o select pode ser desabilitado, quando você está tentando desabilitar algum formcontrol chamado first? `:)
AJT82
Foi apenas um erro de digitação. Eu quero desabilitar a seleção. Pode me ajudar?
Renato Souza de Oliveira
Você poderia reproduzir um êmbolo?
AJT82 de
Você está tentando desativar todo o select? E valuenão é um formArray, é um formControlName. Se você quiser valueser um formArray, terá que alterá-lo. Atualmente é um formControlName. Então, se você quiser que todo o campo de seleção seja desabilitado, basta mudar <select formArrayName="value">para<select formControlName="value">
AJT82

Respostas:

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

ou

this.form.controls['name'].disable();
Joche Wis
fonte
se eu definir um valor como esse -> país: [{valor: this.address.country, disabled: true}] o valor não preenche
Silvio Troia
Usei a mesma técnica para desabilitar campos que foram preenchidos automaticamente por fontes confiáveis. Eu tenho uma opção para habilitar / desabilitar o formulário, e depois de habilitar todo o formulário, eu geralmente desabilito esses campos usando ifinstruções. Depois que o formulário é enviado, todo o formulário é desativado novamente.
retr0 de
72

Preste atenção

Se você estiver criando um formulário usando uma variável para condição e tentando alterá-la mais tarde, ele não funcionará, ou seja, o formulário não será alterado .

Por exemplo

this.isDisabled = true;

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

e se você mudar a variável

this.isDisabled = false;

a forma não mudará. Você deveria usar

this.cardForm.get ('número'). disable ();

BTW.

Você deve usar o método patchValue para alterar o valor:

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

É uma má prática usar desativar em um DOM com formas reativas. Você pode definir esta opção em seu FormControl, ao iniciar o de

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

Propriedade valuenão é necessária

Ou você pode obter seu controle de formulário com get('control_name')e definirdisable

this.userForm.get('username').disable();
Volodymyr Khmil
fonte
Por que é uma má prática usar desabilitar no DOM com formas reativas?
pumpkinthehead
2
Você receberá um aviso do 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. Portanto, a maneira recomendada de alterar o estado de habilitar / desabilitar diretamente por meio dos controles. Além disso, você pode verificar este ótimo tópico netbasal.com/…
Volodymyr Khmil
10

Eu resolvi isso envolvendo meu objeto de entrada com seu rótulo em um conjunto de campos: O conjunto de campos deve ter a propriedade disabled ligada ao booleano

 <fieldset [disabled]="isAnonymous">
    <label class="control-label" for="firstName">FirstName</label>
    <input class="form-control" id="firstName" type="text" formControlName="firstName" />
 </fieldset>
Fernando M
fonte
1
Perdi muito tempo tentando descobrir como desativar os controles em formas reativas, LOL! isso funcionou .. sem diretivas ou código extra necessário. saúde 🍻
Nexus
7

O disablingFormControl preventsdeve estar presente em um formulário while saving. Você pode apenas definir a readonlypropriedade.

E você pode conseguir desta forma:

HTML:

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

TS:

this.disbaleSelect = true;

Encontrei isso aqui

Alex Po
fonte
2
Você pode usar form.getRawValue()para incluir os valores dos controles desativados
Murhaf Sousli
6

Se usar disabledelementos de entrada de formulário (como sugerido na resposta correta como desabilitar a entrada ), a validação para eles também será desabilitada, preste atenção a isso!

(E se você estiver usando o botão de envio, [disabled]="!form.valid"ele excluirá seu campo da validação)

insira a descrição da imagem aqui

Alex Efimov
fonte
1
Como você pode validar para campos que estão inicialmente desabilitados, mas são definidos dinamicamente?
NeptuneOyster
5

Uma abordagem mais geral seria.

// 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
fonte
3

Se você deseja desabilitar first(formcontrol), então você pode usar a instrução abaixo.

this.form.first.disable();

Gampesh
fonte
3

Isso funcionou para mim: this.form.get('first').disable({onlySelf: true});

Foram Jhaveri
fonte
3
this.form.enable()
this.form.disable()

Ou formcontrol 'primeiro'

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

Você pode definir desativar ou ativar no conjunto inicial.

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

insira a descrição da imagem aqui

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

A melhor solução está aqui:

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

Esboço da solução (em caso de link quebrado):

(1) Crie uma diretiva

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) Use-o assim

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

(3) Uma vez que as entradas desativadas não são exibidas em form.value no envio, você pode precisar usar o seguinte (se necessário):

onSubmit(form) {
  const formValue = form.getRawValue() // gets form.value including disabled controls
  console.log(formValue)
}
danday74
fonte
Eu tentei dessa forma. Estou mostrando a maioria dos meus FormControls depois de extrair os dados da API, então, depois de definir / corrigir o valor do meu formControl usando this.form.get('FIELD_NAME').patchValue(DYNAMIC_VALUE), mostro o formControl. quando passou para a diretiva, mostra Não é possível ler a propriedade 'desativar' de indefinido
ImFarhad
0

Eu tive o mesmo problema, mas chamar this.form.controls ['name']. Disable () não corrigiu isso porque eu estava recarregando minha visualização (usando router.navigate ()).

No meu caso, tive que redefinir meu formulário antes de recarregar:

this.form = indefinido; this.router.navigate ([caminho]);

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

Você pode declarar uma função para ativar / desativar todo o controle do formulário:

  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 usar assim

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

Para fazer um campo desabilitar e habilitar de angular forma reactiva 2+

1. Para desativar

  • Adicione [attr.disabled] = "true" à entrada.

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

Para habilitar

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

Habilitar formulário inteiro

this.formname.enable();

Habilitar campo específico sozinho

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

o mesmo para desativar, substitua ativar () por desativar ().

Isso funciona bem. Comentário para consultas.

Srinivasan N
fonte