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?


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

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

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

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>

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


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


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

3

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

this.form.first.disable();


3

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


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)

2

insira a descrição da imagem aqui

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

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

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



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

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

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.