Как добавить обязательную проверку в matInput, если флажок установлен

#javascript #angular #typescript #validation #angular-forms

#javascript #angular #typescript #проверка #угловые формы

Вопрос:

У меня есть 5 флажков в FormGroup, отображаемых с использованием ngFor, и 1 matInput, который должен быть обязательным полем, если установлен какой-либо из флажков.

.ts

 this.gridForm = this.fb.group({
      cbox1: [''],
      cbox2: [''],
      cbox3: [''],
      cbox4: [''],
      cbox5: [''],
      input1: ['', Validators.required] });
  

.html

             <div *ngFor="let table of xTables; let i = index;">
              <mat-checkbox formControlName="{{xTableKeys[i]}}">{{table}}</mat-checkbox>
            </div>
            <mat-form-field>
              <input matInput formControlName="xType" placeholder="X Type">
            </mat-form-field>
  

Я добавил обязательные валидаторы для ввода, но мне нужно, чтобы это требовалось только после того, как установлен любой из флажков. Текущий статус: я не могу отправить форму, если не заполню ввод, но с или без установки флажка.

Комментарии:

1. потому что вы используете одну и ту же переменную enableInput для всех входных данных, и вам нужен уникальный для каждого

Ответ №1:

Вы можете использовать пользовательский валидатор:

 
    this.gridForm = this.fb.group({
          cbox1: [''],
          cbox2: [''],
          cbox3: [''],
          cbox4: [''],
          cbox5: [''],
          input1: ['', [requiredIfValidator(() => this.gridForm.get('cbox1' amp;amp; 'cbox2' amp;amp; 'cbox3' amp;amp; 'cbox4' amp;amp; 'cbox5').value)]] 
    });
    
        function requiredIfValidator(predicate) {
          return (formControl => {
            if (!formControl.parent) {
              return null;
            }
            if (formControl.parent.get('cbox1').value) {
              return Validators.required(formControl);
            }
            if (formControl.parent.get('cbox2').value) {
              return Validators.required(formControl);
            }
            if (formControl.parent.get('cbox3').value) {
              return Validators.required(formControl);
            }
            if (formControl.parent.get('cbox4').value) {
              return Validators.required(formControl);
            }
            if (formControl.parent.get('cbox5').value) {
              return Validators.required(formControl);
            }
            return null;
          })
        };
  

Подпишитесь на изменения значений, чтобы инициировать условную проверку при переключении флажка.

 
    this.gridForm.get('cbox1').valueChanges
      .subscribe(value => {
        this.gridForm.get('input1').updateValueAndValidity();
      });
    this.gridForm.get('cbox2').valueChanges
      .subscribe(value => {
        this.gridForm.get('input1').updateValueAndValidity();
      });
    this.gridForm.get('cbox3').valueChanges
      .subscribe(value => {
        this.gridForm.get('input1').updateValueAndValidity();
      });
    this.gridForm.get('cbox4').valueChanges
      .subscribe(value => {
        this.gridForm.get('input1').updateValueAndValidity();
      });
    this.gridForm.get('cbox5').valueChanges
      .subscribe(value => {
        this.gridForm.get('input1').updateValueAndValidity();
      });

  

Это называется пользовательским средством проверки условных полей.
Проверьте эту ссылку https://medium.com/ngx/3-ways-to-implement-conditional-validation-of-reactive-forms-c59ed6fc3325

Комментарии:

1. Это работает. Большое спасибо! Предоставленная ссылка очень полезна

Ответ №2:

enableInput также должен быть массивом. В противном случае он будет принимать только значение последнего обновленного флажка.

 <div *ngFor="let table of xTables; let i = index;">
    <mat-checkbox formControlName="{{xTableKeys[i]}}" [checked]="enableInput[i]" 
    (change)="enableInput[i] = !enableInput[i]">{{table}}</mat-checkbox>
</div>
<mat-form-field>
    <input matInput formControlName="xType" placeholder="X Type" 
    [attr.disabled]="getInputState()">
</mat-form-field>
  
 
public enableInput = [];

getInputState() {
    // checkboxStatus sets to true if at least one checkbox is checked
    const checkboxStatus = this.enableInput.find(checkboxVal => checkboxVal) ? true : false;
    return checkboxStatus;
}
  

Комментарии:

1. enableInput должен быть инициализирован пустым массивом. Я обновил ответ

2. Спасибо. ошибка исправлена. но вместо этого ввод становится отключенным, как только я установил флажок. Попытался переключить статус «нет», но то же самое. Ввод должен быть отключен после загрузки страницы, есть идеи?

3. Я изменил проверку, чтобы использовать троичное условие, не могли бы вы попробовать с обновленным решением?

4. Пробовал. Ввод все еще находился в состоянии включения при загрузке страницы. Большое спасибо за помощь, я отредактировал свой вопрос, чтобы попробовать другой способ, не могли бы вы взглянуть?