Deshabilitar campos de entrada en forma reactiva

117

¡Ya intenté seguir el ejemplo de otras respuestas de aquí y no lo logré!

Creé un formulario reactivo (es decir, dinámico) y quiero deshabilitar algunos campos en cualquier momento. Mi código de formulario:

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

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

Reduje el código para facilitar. Quiero deshabilitar el campo de tipo seleccionar. Intenté hacer lo siguiente:

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

¡no funciona! alguien tiene una sugerencia?

Renato Souza de Oliveira
fuente
¿Cómo podría deshabilitarse la selección, cuando está intentando deshabilitar algún control de formulario llamado first? `:)
AJT82
Fue solo un error tipográfico. Quiero deshabilitar la selección. ¿Me puedes ayudar?
Renato Souza de Oliveira
¿Podrías reproducir un plunker?
AJT82
¿Estás intentando desactivar toda la selección? Y valueno es un formArray, es un formControlName. Si desea valueser un formArray, tendrá que cambiarlo. Actualmente es un formControlName. Entonces, si desea que todo el campo de selección esté deshabilitado, simplemente cambie <select formArrayName="value">a<select formControlName="value">
AJT82

Respuestas:

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

o

this.form.controls['name'].disable();
Joche Wis
fuente
si establezco un valor como ese -> país: [{valor: this.address.country, disabled: true}] el valor no se completa
Silvio Troia
He usado la misma técnica para deshabilitar los campos que se completaron automáticamente desde fuentes confiables. Tengo un interruptor para habilitar / deshabilitar el formulario, y después de habilitar todo el formulario, generalmente deshabilito esos campos usando ifdeclaraciones. Una vez enviado el formulario, el formulario completo se desactiva una vez más.
retr0
72

Presta atención

Si está creando un formulario usando una variable para condición y tratando de cambiarlo más tarde, no funcionará, es decir, el formulario no cambiará .

Por ejemplo

this.isDisabled = true;

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

y si cambias la variable

this.isDisabled = false;

la forma no cambiará. Deberías usar

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

Por cierto.

Debe usar el método patchValue para cambiar el valor:

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

Es una mala práctica usar deshabilitar en un DOM con formas reactivas. Puede configurar esta opción en su FormControl, cuando inicie desde

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

Propiedad value no es necesaria

O puede obtener su control de formulario con get('control_name')y configurardisable

this.userForm.get('username').disable();
Volodymyr Khmil
fuente
¿Por qué es una mala práctica utilizar deshabilitar en el DOM con formas reactivas?
pumpkinthehead
2
Recibirá una advertencia de 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. Entonces, la forma recomendada de cambiar el estado de deshabilitar / habilitar directamente a través de los controles. Además, puede consultar este gran tema netbasal.com/…
Volodymyr Khmil
10

Lo resolví envolviendo mi objeto de entrada con su etiqueta en un conjunto de campos: el conjunto de campos debe tener la propiedad deshabilitada vinculada al 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
fuente
1
Perdí mucho tiempo averiguando cómo deshabilitar los controles en formas reactivas, ¡LOL! esto funcionó ... no se necesitan directivas ni código adicional. salud 🍻
Nexus
7

El disablingFormControl preventsdebe estar presente en un formulario mientrassaving . Simplemente puede configurar la readonlypropiedad.

Y puedes lograrlo de esta manera:

HTML:

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

TS:

this.disbaleSelect = true;

Encontré esto aquí

Alex Po
fuente
2
Puede usar form.getRawValue()para incluir los valores de controles deshabilitados
Murhaf Sousli
6

Si para usar disabledelementos de entrada de formulario (como se sugiere en la respuesta correcta cómo deshabilitar la entrada ), la validación para ellos también se deshabilitará, ¡preste atención a eso!

(Y si está utilizando el botón enviar [disabled]="!form.valid", excluirá su campo de la validación)

ingrese la descripción de la imagen aquí

Alex Efimov
fuente
1
¿Cómo se pueden validar los campos que inicialmente están deshabilitados pero que se configuran dinámicamente?
NeptuneOyster
5

Un enfoque más general sería.

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

Si desea deshabilitar first(control de formulario), puede usar la siguiente declaración.

this.form.first.disable();

Gampesh
fuente
3

Esto funcionó para mí: this.form.get('first').disable({onlySelf: true});

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

O formcontrol 'primero'

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

Puede configurar deshabilitar o habilitar en la configuración inicial.

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

ingrese la descripción de la imagen aquí

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

La mejor solución está aquí:

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

Esquema de la solución (en caso de enlace roto):

(1) Cree una directiva

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) Úselo así

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

(3) Dado que las entradas deshabilitadas no se muestran en form.value al enviar, es posible que deba usar lo siguiente en su lugar (si es necesario):

onSubmit(form) {
  const formValue = form.getRawValue() // gets form.value including disabled controls
  console.log(formValue)
}
danday74
fuente
Intenté de esta manera. Estoy mostrando la mayoría de mis FormControls después de extraer los datos de la API, por lo que después de configurar / parchear el valor de mi formControl usando this.form.get('FIELD_NAME').patchValue(DYNAMIC_VALUE), muestro el formControl. cuando pasó a la directiva, muestra No se puede leer la propiedad 'deshabilitar' de indefinido
ImFarhad
0

Tuve el mismo problema, pero llamar a this.form.controls ['nombre']. Disable () no lo solucionó porque estaba recargando mi vista (usando router.navigate ()).

En mi caso tuve que restablecer mi formulario antes de recargar:

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

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

Puede declarar una función para habilitar / deshabilitar todo el control de formulario:

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

y úsalo así

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

Para hacer un campo deshabilitar y habilitar de forma reactiva angular 2+

1. Para deshabilitar

  • Agregue [attr.disabled] = "true" a la entrada.

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

Para permitir

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

Habilitar formulario completo

this.formname.enable();

Habilitar un campo particular solo

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

lo mismo para deshabilitar, reemplace enable () con deshabilitar ().

Esto funciona bien. Comentario para consultas.

Srinivasan N
fuente