Angular2 FormBuilder Validatiors: требуется заполнить хотя бы одно поле в группе
У меня есть форма, где я собираю телефонные номера (мобильные, личные и другие). Мне нужно иметь хотя бы заполненный вход. Я пытаюсь использовать Angular2 FormBuilder.
После долгих исследований у меня возникла проблема с решением этой проблемы. Я знаю, что могу сделать это, используя другие методы, но мне было интересно, возможно ли это использовать FormBuilder Validators. Если я добавлю "Validators.required", тогда требуются все 3 поля. Любые предложения или идеи?
phone: this._fb.group(
{
other: [''],
personal: [''],
mobile: [''],
}
Основываясь на подсказке "JB Nizet", здесь я должен был реализовать, чтобы заставить ее работать:
Мой групповой валидатор (он все еще нуждается в настройке):
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 }
)
Мне потребовалось некоторое время, но ключ должен добавить ключевое слово "валидатор", и это приведет к срабатыванию модуля проверки подлинности группы.
В HTML я добавил следующее:
<small *ngIf="!myForm.controls.profile.controls.phone.valid" class="text-danger">
At least one phone is required.
</small>
Я надеюсь, что это поможет кому-то еще.
Ответы
Ответ 1
Я использую функцию 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 };
};
{
phone: this._fb.group({
other: [''],
personal: [''],
mobile: [''],
}, { validator: atLeastOne(Validators.required) })
}
Ответ 2
Это общий код, который можно использовать с каждой группой 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);
}
}