web-dev-qa-db-ja.com

Angular2 FormBuilder Validatiors:グループ内の少なくとも1つのフィールドに入力する必要があります

電話番号(モバイル、個人、その他)を収集するフォームがあります。少なくとも入力を入力する必要があります。 Angular2 FormBuilderを使用しようとしています。

多くの研究の後、私はこの問題を回避するのに問題があります。私は他の方法を使用してそれを行うことができることを知っていますが、FormBuilder Validatorsを使用してそれが可能かどうか疑問に思っていました。 「Validators.required」を追加すると、3つのフィールドすべてが必須になります。提案やアイデアはありますか?

phone: this._fb.group(
                    {
                        other: [''],
                        personal: [''],
                        mobile: [''],
                    }

「JB Nizet」のヒントに基づいて、これを機能させるために実装する必要がありました。

私のグループValidator(まだ調整が必要です):

static phoneExists(group: FormGroup): { [key: string]: any } {

    if (null != group) {
        var other: AbstractControl = group.controls['other'];
        var mobile: AbstractControl = group.controls['mobile'];
        var personal: AbstractControl = group.controls['personal'];
        var data: Object = group.value;

        return (
            (other.valid && isEmptyInputValue(other.value))
            && (mobile.valid && isEmptyInputValue(mobile.value))
            && (personal.valid && isEmptyInputValue(personal.value))
            )
            ? { 'required': true }
            : null;
    }
}

私のグループの変更:

phone: this._fb.group(
                    {
                        other: [''],
                        personal: [''],
                        mobile: [''],
                    },
                    { validator: MyValidators.phoneExists }
                )

しばらく時間がかかりましたが、重要なのは「Word」バリデーターというキーを追加することです。これにより、グループバリデーターが起動します。

HTMLに次を追加しました。

<small *ngIf="!myForm.controls.profile.controls.phone.valid" class="text-danger">
                                        At least one phone is required.
                                    </small>

これが他の人に役立つことを願っています。

21
Manny

既存のバリデータに基づいてカスタムバリデータを作成するatLeastOne関数を使用します。

import { FormGroup, ValidationErrors, ValidatorFn } from '@angular/forms';

export const atLeastOne = (validator: ValidatorFn) => (
  group: FormGroup,
): ValidationErrors | null => {
  const hasAtLeastOne =
    group &&
    group.controls &&
    Object.keys(group.controls).some(k => !validator(group.controls[k]));

  return hasAtLeastOne ? null : { atLeastOne: true };
};

美しさは、Validators.requiredだけでなく、任意のバリデーターを使用できることです。

OPの場合、次のように使用されます。

{
  phone: this._fb.group({
    other: [''],
    personal: [''],
    mobile: [''],
  }, { validator: atLeastOne(Validators.required) })
}
27
Merott

これは、すべてのFormGroupで使用できる汎用コードです。

export function AtLeastOneFieldValidator(group: FormGroup): {[key: string]: any} {
  let isAtLeastOne = false;
  if (group && group.controls) {
    for (const control in group.controls) {
      if (group.controls.hasOwnProperty(control) && group.controls[control].valid && group.controls[control].value) {
        isAtLeastOne = true;
        break;
      }
    }
  }
  return isAtLeastOne ? null : { 'required': true };
}

そして使用法:

@Component({
  selector: 'app-customers',
  templateUrl: './customers.component.html',
  styleUrls: ['./customers.component.scss']
})
export class CustomersComponent implements OnInit {

  public searchCustomerForm: FormGroup;

  constructor() { }

  ngOnInit() {
    this.searchCustomerForm = new FormGroup({
      customerID: new FormControl(''),
      customerEmail: new FormControl(''),
      customerFirstName: new FormControl(''),
      customerLastName: new FormControl('')
    }, AtLeastOneFieldValidator);
  }
}
8
AnTiToinE