Отключить поля ввода в реактивной форме

118

Я уже пробовал следовать примеру других ответов отсюда, и мне это не удалось!

Я создал реактивную форму (т. Е. Динамическую) и хочу в любой момент отключить некоторые поля. Мой код формы:

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

мой 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>

Я сократил код для облегчения. Я хочу отключить поле выбора типа. Я пытался сделать следующее:

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

не работает! Есть ли у кого-нибудь предложения?

Ренато Соуза де Оливейра
источник
Как можно было отключить выбор, когда вы пытаетесь отключить какой-либо вызываемый элемент управления формой first? `:)
AJT82
Это была просто опечатка. Я хочу отключить выбор. Вы можете помочь мне?
Ренато Соуза де Оливейра
Не могли бы вы воспроизвести плункер?
AJT82
Вы пытаетесь отключить весь выбор? И valueэто не formArray, это formControlName. Если вы хотите valueбыть formArray, вам придется его изменить. В настоящее время это formControlName. Поэтому, если вы хотите, чтобы все поле выбора было отключено, просто измените его <select formArrayName="value">на<select formControlName="value">
AJT82

Ответы:

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

или

this.form.controls['name'].disable();
Joche Wis
источник
если я установил такое значение -> country: [{value: this.address.country, disabled: true}] значение не заполняется
Сильвио Троя
Я использовал ту же технику, чтобы отключить поля, которые были автоматически заполнены из надежных источников. У меня есть переключатель для включения / отключения формы, и после включения всей формы я обычно отключаю эти поля с помощью ifоператоров. После отправки формы вся форма снова отключается.
retr0
72

Обращать внимание

Если вы создаете форму с использованием переменной для условия и пытаетесь изменить ее позже, это не сработает, т.е. форма не изменится .

Например

this.isDisabled = true;

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

и если вы измените переменную

this.isDisabled = false;

форма не изменится. Вы должны использовать

this.cardForm.get ('число'). disable ();

Кстати.

Вы должны использовать метод patchValue для изменения значения:

this.cardForm.patchValue({
    'number': '1703'
});
Дмитрий Гринько
источник
22

Использование disable в DOM с реактивными формами - плохая практика. Вы можете установить эту опцию в своем FormControl, когда вы запускаете из

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

Собственность valueне нужна

Или вы можете получить контроль над формой с помощью get('control_name')и установитьdisable

this.userForm.get('username').disable();
Владимир Хмиль
источник
Почему использование disable в DOM с реактивными формами - плохая практика?
pumpkinthehead
2
Вы получите предупреждение от 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. Итак, рекомендуемый способ изменить состояние отключения / включения напрямую через элементы управления. Также вы можете проверить эту замечательную тему netbasal.com/…
Владимир Хмиль
10

Я решил это, заключив свой входной объект с его меткой в ​​набор полей: у набора полей должно быть свойство disabled, привязанное к логическому

 <fieldset [disabled]="isAnonymous">
    <label class="control-label" for="firstName">FirstName</label>
    <input class="form-control" id="firstName" type="text" formControlName="firstName" />
 </fieldset>
Фернандо М
источник
1
потратил много времени на выяснение того, как отключить элементы управления в реактивных формах, LOL! это сработало .. никаких директив или дополнительного кода не требуется. ура 🍻
Nexus
7

disablingFormControl preventsона может присутствовать в форме , в то время saving. Вы можете просто установить это readonlyсвойство.

А добиться этого можно так:

HTML:

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

TS:

this.disbaleSelect = true;

Нашел это здесь

Алекс По
источник
2
Вы можете использовать form.getRawValue()для включения отключенных значений элементов управления
Мурхаф Сусли,
6

Если использовать disabledэлементы ввода формы (например, предложенные в правильном ответе, как отключить ввод ), проверка для них также будет отключена, обратите на это внимание!

(И если вы используете кнопку отправки, как будто [disabled]="!form.valid"это исключит ваше поле из проверки)

введите описание изображения здесь

Алексей Ефимов
источник
1
Как вы можете проверить поля, которые изначально отключены, но устанавливаются динамически?
NeptuneOyster
5

Был бы более общий подход.

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

Если вы хотите отключить first(formcontrol), вы можете использовать инструкцию ниже.

this.form.first.disable();

Гампеш
источник
3

Это сработало для меня: this.form.get('first').disable({onlySelf: true});

Форам Джавери
источник
3
this.form.enable()
this.form.disable()

Или formcontrol 'сначала'

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

Вы можете отключить или включить при первоначальной настройке.

 first: new FormControl({disabled: true}, Validators.required)
Пу Чэнли
источник
2

введите описание изображения здесь

lastName: new FormControl({value: '', disabled: true}, Validators.compose([Validators.required])),
Абдулла Парияни
источник
1

Лучшее решение здесь:

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

Схема решения (в случае неработающей ссылки):

(1) Создайте директиву

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) Используйте это так

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

(3) Поскольку отключенные входы не отображаются в form.value при отправке, вам может потребоваться использовать следующее (при необходимости):

onSubmit(form) {
  const formValue = form.getRawValue() // gets form.value including disabled controls
  console.log(formValue)
}
danday74
источник
Я пробовал вот так. Я показываю большую часть своих FormControl после получения данных API, поэтому после установки / исправления значения для моего formControl с помощью this.form.get('FIELD_NAME').patchValue(DYNAMIC_VALUE)я показываю formControl. когда он передается в директиву, он показывает Cannot read property 'disable' of undefined
ImFarhad
0

У меня была та же проблема, но вызов this.form.controls ['name']. Disable () не устранил ее, потому что я перезагружал свое представление (используя router.navigate ()).

В моем случае мне пришлось сбросить форму перед перезагрузкой:

this.form = undefined; this.router.navigate ([путь]);

Тай Чыонг
источник
0
setTimeout(() => { emailGroup.disable(); });
Джадсон Террелл
источник
0

Вы можете объявить функцию для включения / отключения всех элементов управления формой:

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

и используйте это так

this.toggleDisableFormControl(true, ['email']);
// disbale all field but email
Дуонг Ле
источник
-2

Для того, чтобы сделать поле Отключить и включить в реактивной форме углового 2+

1. Чтобы отключить

  • Добавьте во ввод [attr.disabled] = "true" .

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

Включить

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

Включить всю форму

this.formname.enable();

Включить только конкретное поле

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

То же самое для disable, замените enable () на disable ().

Это прекрасно работает. Комментарии к запросам.

Шринивасан Н
источник