8

我正在使用 angular 4 形式,并且我有一些字段。名字、姓氏和公司对我来说真的很重要。我想强制用户填写这三个字段之一。我该怎么做?

这里是 .ts 代码:

this.contactForm = this.fb.group({
        first_name: [null, Validators.compose([Validators.required])],
        last_name: [null, Validators.compose([Validators.required])],
        email: [null, Validators.compose([this.validateEmail])],
        company: [null],
        position: [null],
      });

一个html:

 <form [formGroup]="contactForm" fxLayout="column">
            <md-input-container class="data_light">
              <input class="data_font capital" mdInput placeholder="{{'Contacts.FirstName' | translate}}" [formControl]="contactForm.controls['first_name']">
            </md-input-container>
            <small *ngIf="contactForm.controls['first_name'].hasError('required') && contactForm.controls['first_name'].touched" class="mat-text-warn data_light">{{'Contacts.firstNameReq' | translate}}
            </small>
            <md-input-container class="data_light">
              <input class="data_font capital" mdInput placeholder="{{'Contacts.lastName' | translate}}" [formControl]="contactForm.controls['last_name']">
            </md-input-container>
            <small *ngIf="contactForm.controls['last_name'].hasError('required') && contactForm.controls['last_name'].touched" class="mat-text-warn data_light">{{'Contacts.lastNameReq' | translate}}
            </small>
            <md-input-container class="data_light">
              <input class="data_font" mdInput placeholder="{{'Contacts.email' | translate}}" [formControl]="contactForm.controls['email']"
                (blur)="checkContactEmail()">
            </md-input-container>
            <small *ngIf="contactForm.controls['email'].hasError('validateEmail') && contactForm.controls['email'].dirty" class="mat-text-warn data_light">{{'Contacts.emailValid' | translate}}
            </small>
            <small *ngIf="!emailValid" class="mat-text-warn data_light">{{emailMessage}}
            </small>
            <md-input-container class="data_light">
              <input class="data_font capital" mdInput placeholder="{{'Contacts.Company' | translate}}" [formControl]="contactForm.controls['company']">
            </md-input-container>
            <md-input-container class="data_light">
              <input class="data_font capital" mdInput placeholder="{{'Contacts.Position' | translate}}" [formControl]="contactForm.controls['position']">
            </md-input-container>
          </form>
4

4 回答 4

32
private atLeastOneValidator = () => {
    return (controlGroup) => {
        let controls = controlGroup.controls;
        if ( controls ) {
            let theOne = Object.keys(controls).find(key=> controls[key].value!=='');
            if ( !theOne ) {
                return {
                    atLeastOneRequired : {
                        text : 'At least one should be selected'
                    }
                }
            }
        }
        return null;
    };
};

上面是一个可重用的验证器,你可以像这样使用它:

 this.contactForm.setValidators(this.atLeastOneValidator())

contactForm如果没有字段具有值,这会使整个无效。

请注意,contactForm的默认验证仍然可以很好地工作,您不必关心表单中的字段数量,并且所有内容都是动态处理的

编辑 :

请注意,atLeastOneValidator正在检查值是否为空,但如果您想说:

至少其中一个字段必须是valid,然后您可以简单地将条件调整为以下

 let theOne = Object.keys(controls).find(key=> controls[key].valid );

然后,您可以像这样在模板中使用错误:

 <small *ngIf="contactForm.hasError('atLeastOneRequired')" class="mat-text-warn data_light">{{contactForm.getError('atLeastOneRequired')}}
        </small>
于 2018-04-26T07:28:12.947 回答
2

禁用您的按钮,直到用户未填写必填字段

<button type='submit' [disabled]='!contactForm.valid'> Submit</button>

然后像这样调用函数来检查禁用

<button type='submit' [disabled]='checkValid()'> Submit</button>
checkValid() {
  if(this.contactForm.get('first_name').valid || this.contactForm.get('last_name').valid || this.contactForm.get('email').valid) {
    return false;
  } else {
    return true;
  }
}
于 2018-04-26T07:20:30.750 回答
0

您可以使用以下验证器


  AtLeastOneInputHasValue = () => {
    return (group: FormGroup) => {
      if (!Object.values(group.value).find(value => value !== '')) {
        return { message: 'Please input at least one value' }
      }
      return null
    }
  }

并将其添加到您的表单组验证器中

this.contactForm = this.fb.group({
      ...
      }, 
      this.AtLeastOneInputHasValue()
    );

disabled如果表单上的任何验证器无效,则在您的模板上使用按钮

<button type='submit' [disabled]='!contactForm.valid'> Submit</button>
于 2020-01-29T02:54:10.110 回答
0

我只为某些字段提供了更好的自定义方式,而不是为表单的所有字段。还,

  • 不是这样<button [disabled]="checkValid()">的,

  • 但是直接使用<button [disabled]="form.invalid || form.pristine || loading">

可以通过 Array 参数提供字段,如下所示:

export const atLeastOneHasValue = (fields: Array<string>) => {
    return (group: FormGroup) => {
        for (const fieldName of fields) {
            if (group.get(fieldName).value) {
                return null;
            }
        }
        return { paymentMethodRequired: true };
    };
};

// Form group
form = this.formBuilder.group({
   field1: [],
   field2: [],
   field3: [],
   field4: []
}, {
    validators: atLeastOneHasValue(['field2', 'field3'])
});

然后,您可以在模板中检查并显示以下错误,由于form.invalid布尔值,保存按钮将被禁用:

<mat-error *ngIf="form.hasError('paymentMethodRequired')">
    {{"ERROR_PAYMENT_METHOD_REQUIRED" | translate}}
</mat-error>
于 2021-08-22T21:46:43.307 回答