Angular2 FormBuilder Validatiors: require at least one field in a group to be filled

谁说胖子不能爱 提交于 2019-12-29 18:39:08

问题


I have a form where I'm collecting phone numbers (mobile, personal, other). I need to have at least input populated. I'm trying to use Angular2 FormBuilder.

After much research I'm having a problem getting my head around this problem. I know I can do it using other methods but I was wondering if it's possible using FormBuilder Validators. If I add "Validators.required" then all 3 fields are required. Any suggestions or ideas?

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

Base on the hint from " JB Nizet", here's what I had to implement to make it work:

My group Validator (it still needs tweaking):

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

My group change:

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

It took me a while, but the key is to add the key word "validator" and it will cause the group validator to fire.

In the HTML i added the following:

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

I hope this help anyone else.


回答1:


I use an atLeastOne function that creates a custom validator based on any existing validator:

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

The beauty is that you can use any validator with it and not just Validators.required.

In OP's case, it'll be used like this:

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



回答2:


This is a generic code that you can use with every 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 };
}

And the usage:

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


来源:https://stackoverflow.com/questions/40321033/angular2-formbuilder-validatiors-require-at-least-one-field-in-a-group-to-be-fi

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!