- Form表单
- 表单
- 表单项 nz-form-item
- 表单标签 nz-form-label
- 表单域 nz-form-control
- 单独引入此组件
- 代码演示
- API
- [nz-form]directive
- nz-form-itemcomponent
- nz-form-labelcomponent
- nz-form-controlcomponent
- nz-form-splitcomponent
- nz-form-textcomponent
- 表单
Form表单
具有数据收集、校验和提交功能的表单,包含复选框、单选框、输入框、下拉选择框等元素。
该组件需要与 Angular表单 结合使用,开发者根据需要可以自由选择 响应式表单 或 模板驱动表单.
使用该组件前请确保您已经阅读并掌握了 Forms 的使用方式。
表单
我们提供了以下三种排列方式:
- 水平排列:标签和表单控件水平排列;(默认)
- 垂直排列:标签和表单控件上下垂直排列;
- 行内排列:表单项水平行内排列。
表单项 nz-form-item
表单项用于区分表单中不同的区域,包含表单域和表单标签(可选)。
表单标签 nz-form-label
用于标示当前表单项的内容,可选。
表单域 nz-form-control
表单一定会包含表单域,表单域可以是输入控件,标准表单域,标签,下拉菜单,文本域等。
<form nz-form><nz-form-item><nz-form-label [nzSpan]="6" nzFor="email">E-mail</nz-form-label><nz-form-control [nzSpan]="14"><input nz-input name="email" type="email" id="email"></nz-form-control></nz-form-item ></form>
单独引入此组件
想要了解更多关于单独引入组件的内容,可以在快速上手页面进行查看。
import { NzFormModule } from 'ng-zorro-antd/form';
代码演示

内联登录栏
内联登录栏,常用在顶部导航栏中。
import { Component, OnInit } from '@angular/core';import { FormBuilder, FormGroup, Validators } from '@angular/forms';@Component({selector: 'nz-demo-form-horizontal-login',template: `<form nz-form [nzLayout]="'inline'" [formGroup]="validateForm" (ngSubmit)="submitForm()"><nz-form-item><nz-form-control nzErrorTip="Please input your username!"><nz-input-group nzPrefixIcon="user"><input formControlName="userName" nz-input placeholder="Username" /></nz-input-group></nz-form-control></nz-form-item><nz-form-item><nz-form-control nzErrorTip="Please input your Password!"><nz-input-group nzPrefixIcon="lock"><input formControlName="password" nz-input type="password" placeholder="Password" /></nz-input-group></nz-form-control></nz-form-item><nz-form-item><nz-form-control><button nz-button nzType="primary" [disabled]="!validateForm.valid">Log in</button></nz-form-control></nz-form-item></form>`})export class NzDemoFormHorizontalLoginComponent implements OnInit {validateForm: FormGroup;submitForm(): void {for (const i in this.validateForm.controls) {this.validateForm.controls[i].markAsDirty();this.validateForm.controls[i].updateValueAndValidity();}}constructor(private fb: FormBuilder) {}ngOnInit(): void {this.validateForm = this.fb.group({userName: [null, [Validators.required]],password: [null, [Validators.required]],remember: [true]});}}

登录框
普通的登录框,可以容纳更多的元素。
import { Component, OnInit } from '@angular/core';import { FormBuilder, FormGroup, Validators } from '@angular/forms';@Component({selector: 'nz-demo-form-normal-login',template: `<form nz-form [formGroup]="validateForm" class="login-form" (ngSubmit)="submitForm()"><nz-form-item><nz-form-control nzErrorTip="Please input your username!"><nz-input-group nzPrefixIcon="user"><input type="text" nz-input formControlName="userName" placeholder="Username" /></nz-input-group></nz-form-control></nz-form-item><nz-form-item><nz-form-control nzErrorTip="Please input your Password!"><nz-input-group nzPrefixIcon="lock"><input type="password" nz-input formControlName="password" placeholder="Password" /></nz-input-group></nz-form-control></nz-form-item><nz-form-item><nz-form-control><label nz-checkbox formControlName="remember"><span>Remember me</span></label><a class="login-form-forgot" class="login-form-forgot">Forgot password</a><button nz-button class="login-form-button" [nzType]="'primary'">Log in</button>Or<a>register now!</a></nz-form-control></nz-form-item></form>`,styles: [`.login-form {max-width: 300px;}.login-form-forgot {float: right;}.login-form-button {width: 100%;}`]})export class NzDemoFormNormalLoginComponent implements OnInit {validateForm: FormGroup;submitForm(): void {for (const i in this.validateForm.controls) {this.validateForm.controls[i].markAsDirty();this.validateForm.controls[i].updateValueAndValidity();}}constructor(private fb: FormBuilder) {}ngOnInit(): void {this.validateForm = this.fb.group({userName: [null, [Validators.required]],password: [null, [Validators.required]],remember: [true]});}}

注册新用户
用户填写必须的信息以注册新用户。
import { Component, OnInit } from '@angular/core';import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';@Component({selector: 'nz-demo-form-register',template: `<form nz-form [formGroup]="validateForm" (ngSubmit)="submitForm()"><nz-form-item><nz-form-label [nzSm]="6" [nzXs]="24" nzRequired nzFor="email">E-mail</nz-form-label><nz-form-control [nzSm]="14" [nzXs]="24" nzErrorTip="The input is not valid E-mail!"><input nz-input formControlName="email" id="email" /></nz-form-control></nz-form-item><nz-form-item><nz-form-label [nzSm]="6" [nzXs]="24" nzFor="password" nzRequired>Password</nz-form-label><nz-form-control [nzSm]="14" [nzXs]="24" nzErrorTip="Please input your password!"><inputnz-inputtype="password"id="password"formControlName="password"(ngModelChange)="updateConfirmValidator()"/></nz-form-control></nz-form-item><nz-form-item><nz-form-label [nzSm]="6" [nzXs]="24" nzFor="checkPassword" nzRequired>Confirm Password</nz-form-label><nz-form-control [nzSm]="14" [nzXs]="24" [nzErrorTip]="errorTpl"><input nz-input type="password" formControlName="checkPassword" id="checkPassword" /><ng-template #errorTpl let-control><ng-container *ngIf="control.hasError('required')">Please confirm your password!</ng-container><ng-container *ngIf="control.hasError('confirm')">Two passwords that you enter is inconsistent!</ng-container></ng-template></nz-form-control></nz-form-item><nz-form-item><nz-form-label [nzSm]="6" [nzXs]="24" nzFor="nickname" nzRequired><span>Nickname<inz-iconnz-tooltipnzTitle="What do you want other to call you"type="question-circle"nzTheme="outline"></i></span></nz-form-label><nz-form-control [nzSm]="14" [nzXs]="24" nzErrorTip="Please input your nickname!"><input nz-input id="nickname" formControlName="nickname" /></nz-form-control></nz-form-item><nz-form-item><nz-form-label [nzSm]="6" [nzXs]="24" nzFor="phoneNumber" nzRequired>Phone Number</nz-form-label><nz-form-control[nzSm]="14"[nzXs]="24"[nzValidateStatus]="validateForm.controls['phoneNumber']"nzErrorTip="Please input your phone number!"><nz-input-group [nzAddOnBefore]="addOnBeforeTemplate"><ng-template #addOnBeforeTemplate><nz-select formControlName="phoneNumberPrefix" class="phone-select"><nz-option nzLabel="+86" nzValue="+86"></nz-option><nz-option nzLabel="+87" nzValue="+87"></nz-option></nz-select></ng-template><input formControlName="phoneNumber" id="'phoneNumber'" nz-input /></nz-input-group></nz-form-control></nz-form-item><nz-form-item><nz-form-label [nzSm]="6" [nzXs]="24" nzFor="website" nzRequired>Website</nz-form-label><nz-form-control [nzSm]="14" [nzXs]="24" nzErrorTip="Please input website!"><input nz-input id="website" formControlName="website" placeholder="website" /></nz-form-control></nz-form-item><nz-form-item><nz-form-label [nzSm]="6" [nzXs]="24" nzFor="captcha" nzRequired>Captcha</nz-form-label><nz-form-control[nzSm]="14"[nzXs]="24"nzErrorTip="Please input the captcha you got!"nzExtra="We must make sure that your are a human."><div nz-row [nzGutter]="8"><div nz-col [nzSpan]="12"><input nz-input formControlName="captcha" id="captcha" /></div><div nz-col [nzSpan]="12"><button nz-button (click)="getCaptcha($event)">Get captcha</button></div></div></nz-form-control></nz-form-item><nz-form-item nz-row class="register-area"><nz-form-control [nzSpan]="14" [nzOffset]="6"><label nz-checkbox formControlName="agree"><span>I have read the <a>agreement</a></span></label></nz-form-control></nz-form-item><nz-form-item nz-row class="register-area"><nz-form-control [nzSpan]="14" [nzOffset]="6"><button nz-button nzType="primary">Register</button></nz-form-control></nz-form-item></form>`,styles: [`[nz-form] {max-width: 600px;}.phone-select {width: 70px;}.register-are {margin-bottom: 8px;}`]})export class NzDemoFormRegisterComponent implements OnInit {validateForm: FormGroup;submitForm(): void {for (const i in this.validateForm.controls) {this.validateForm.controls[i].markAsDirty();this.validateForm.controls[i].updateValueAndValidity();}}updateConfirmValidator(): void {/** wait for refresh value */Promise.resolve().then(() => this.validateForm.controls.checkPassword.updateValueAndValidity());}confirmationValidator = (control: FormControl): { [s: string]: boolean } => {if (!control.value) {return { required: true };} else if (control.value !== this.validateForm.controls.password.value) {return { confirm: true, error: true };}return {};};getCaptcha(e: MouseEvent): void {e.preventDefault();}constructor(private fb: FormBuilder) {}ngOnInit(): void {this.validateForm = this.fb.group({email: [null, [Validators.email, Validators.required]],password: [null, [Validators.required]],checkPassword: [null, [Validators.required, this.confirmationValidator]],nickname: [null, [Validators.required]],phoneNumberPrefix: ['+86'],phoneNumber: [null, [Validators.required]],website: [null, [Validators.required]],captcha: [null, [Validators.required]],agree: [false]});}}

高级搜索
三列栅格式的表单排列方式,常用于数据表格的高级搜索。
有部分定制的样式代码,由于输入标签长度不确定,需要根据具体情况自行调整。
import { Component, OnInit } from '@angular/core';import { FormBuilder, FormControl, FormGroup } from '@angular/forms';@Component({selector: 'nz-demo-form-advanced-search',template: `<form nz-form [formGroup]="validateForm" class="ant-advanced-search-form"><div nz-row [nzGutter]="24"><div nz-col [nzSpan]="8" *ngFor="let control of controlArray" [hidden]="!control.show"><nz-form-item nzFlex><nz-form-label [nzFor]="'field' + control.index">Field {{ control.index }}</nz-form-label><nz-form-control><inputnz-inputplaceholder="placeholder"[formControlName]="'field' + control.index"[attr.id]="'field' + control.index"/></nz-form-control></nz-form-item></div></div><div nz-row><div nz-col [nzSpan]="24" class="search-area"><button nz-button [nzType]="'primary'">Search</button><button nz-button (click)="resetForm()">Clear</button><a class="collapse" (click)="toggleCollapse()">Collapse<i nz-icon [nzType]="isCollapse ? 'down' : 'up'"></i></a></div></div></form><div class="search-result-list">Search Result List</div>`,styles: [`.ant-advanced-search-form {padding: 24px;background: #fbfbfb;border: 1px solid #d9d9d9;border-radius: 6px;}.search-result-list {margin-top: 16px;border: 1px dashed #e9e9e9;border-radius: 6px;background-color: #fafafa;min-height: 200px;text-align: center;padding-top: 80px;}[nz-form-label] {overflow: visible;}button {margin-left: 8px;}.collapse {margin-left: 8px;font-size: 12px;}.search-area {text-align: right;}`]})export class NzDemoFormAdvancedSearchComponent implements OnInit {validateForm: FormGroup;controlArray: any[] = [];isCollapse = true;toggleCollapse(): void {this.isCollapse = !this.isCollapse;this.controlArray.forEach((c, index) => {c.show = this.isCollapse ? index < 6 : true;});}resetForm(): void {this.validateForm.reset();}constructor(private fb: FormBuilder) {}ngOnInit(): void {this.validateForm = this.fb.group({});for (let i = 0; i < 10; i++) {this.controlArray.push({ index: i, show: i < 6 });this.validateForm.addControl(`field${i}`, new FormControl());}}}

动态增减表单项
动态增加、减少表单项。
import { Component, OnInit } from '@angular/core';import { AbstractControl, FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';@Component({selector: 'nz-demo-form-dynamic-form-item',template: `<form nz-form [formGroup]="validateForm" (ngSubmit)="submitForm()"><nz-form-item *ngFor="let control of listOfControl; let i = index"><nz-form-label [nzXs]="24" [nzSm]="4" *ngIf="i == 0" [nzFor]="control.controlInstance">Passengers</nz-form-label><nz-form-control[nzXs]="24"[nzSm]="20"[nzOffset]="i == 0 ? 0 : 4"nzErrorTip="Please input passenger's name or delete this field."><inputclass="passenger-input"nz-inputplaceholder="placeholder"[attr.id]="control.id"[formControlName]="control.controlInstance"/><i nz-icon nzType="minus-circle-o" class="dynamic-delete-button" (click)="removeField(control, $event)"></i></nz-form-control></nz-form-item><nz-form-item><nz-form-control [nzXs]="{ span: 24, offset: 0 }" [nzSm]="{ span: 20, offset: 4 }"><button nz-button nzType="dashed" class="add-button" (click)="addField($event)"><i nz-icon nzType="plus"></i>Add field</button></nz-form-control></nz-form-item><nz-form-item><nz-form-control [nzXs]="{ span: 24, offset: 0 }" [nzSm]="{ span: 20, offset: 4 }"><button nz-button nzType="primary">Submit</button></nz-form-control></nz-form-item></form>`,styles: [`.dynamic-delete-button {cursor: pointer;position: relative;top: 4px;font-size: 24px;color: #999;transition: all 0.3s;}.dynamic-delete-button:hover {color: #777;}.passenger-input {width: 60%;margin-right: 8px;}[nz-form] {max-width: 600px;}.add-button {width: 60%;}`]})export class NzDemoFormDynamicFormItemComponent implements OnInit {validateForm: FormGroup;listOfControl: Array<{ id: number; controlInstance: string }> = [];addField(e?: MouseEvent): void {if (e) {e.preventDefault();}const id = this.listOfControl.length > 0 ? this.listOfControl[this.listOfControl.length - 1].id + 1 : 0;const control = {id,controlInstance: `passenger${id}`};const index = this.listOfControl.push(control);console.log(this.listOfControl[this.listOfControl.length - 1]);this.validateForm.addControl(this.listOfControl[index - 1].controlInstance,new FormControl(null, Validators.required));}removeField(i: { id: number; controlInstance: string }, e: MouseEvent): void {e.preventDefault();if (this.listOfControl.length > 1) {const index = this.listOfControl.indexOf(i);this.listOfControl.splice(index, 1);console.log(this.listOfControl);this.validateForm.removeControl(i.controlInstance);}}getFormControl(name: string): AbstractControl {return this.validateForm.controls[name];}submitForm(): void {for (const i in this.validateForm.controls) {this.validateForm.controls[i].markAsDirty();this.validateForm.controls[i].updateValueAndValidity();}console.log(this.validateForm.value);}constructor(private fb: FormBuilder) {}ngOnInit(): void {this.validateForm = this.fb.group({});this.addField();}}

时间类控件
时间类组件的输入和输出类型均为 Date 类型,可以通过 date-fns 工具库进行进一步的处理。
import { Component, OnInit } from '@angular/core';import { FormBuilder, FormGroup } from '@angular/forms';@Component({selector: 'nz-demo-form-time-related-controls',template: `<form nz-form [formGroup]="validateForm" (ngSubmit)="submitForm()"><nz-form-item><nz-form-label [nzSm]="8" [nzXs]="24" nzRequired>DatePicker</nz-form-label><nz-form-control [nzSm]="16" [nzXs]="24"><nz-date-picker formControlName="datePicker"></nz-date-picker></nz-form-control></nz-form-item><nz-form-item><nz-form-label [nzSm]="8" [nzXs]="24" nzRequired>DatePicker[ShowTime]</nz-form-label><nz-form-control [nzSm]="16" [nzXs]="24"><nz-date-picker nzShowTime formControlName="datePickerTime"></nz-date-picker></nz-form-control></nz-form-item><nz-form-item><nz-form-label [nzSm]="8" [nzXs]="24" nzRequired>MonthPicker</nz-form-label><nz-form-control [nzSm]="16" [nzXs]="24"><nz-month-picker formControlName="monthPicker"></nz-month-picker></nz-form-control></nz-form-item><nz-form-item><nz-form-label [nzSm]="8" [nzXs]="24" nzRequired>RangePicker</nz-form-label><nz-form-control [nzSm]="16" [nzXs]="24"><nz-range-picker formControlName="rangePicker"></nz-range-picker></nz-form-control></nz-form-item><nz-form-item><nz-form-label [nzSm]="8" [nzXs]="24" nzRequired>RangePicker[showTime]</nz-form-label><nz-form-control [nzSm]="16" [nzXs]="24"><nz-range-picker nzShowTime formControlName="rangePickerTime"></nz-range-picker></nz-form-control></nz-form-item><nz-form-item><nz-form-label [nzSm]="8" [nzXs]="24" nzRequired>TimePicker</nz-form-label><nz-form-control [nzSm]="16" [nzXs]="24"><nz-time-picker formControlName="timePicker"></nz-time-picker></nz-form-control></nz-form-item><nz-form-item><nz-form-control [nzXs]="{ span: 24, offset: 0 }" [nzSm]="{ span: 16, offset: 8 }"><button nz-button nzType="primary">Submit</button></nz-form-control></nz-form-item></form>`,styles: [`form {max-width: 600px;}`]})export class NzDemoFormTimeRelatedControlsComponent implements OnInit {validateForm: FormGroup;submitForm(): void {console.log(this.validateForm.value);}constructor(private fb: FormBuilder) {}ngOnInit(): void {this.validateForm = this.fb.group({datePicker: [null],datePickerTime: [null],monthPicker: [null],rangePicker: [[]],rangePickerTime: [[]],timePicker: [null]});}}

响应式表单验证
我们在 nz-form-control 上 提供了 nzValidateStatusnzHasFeedback 等属性,当使用响应式表单时,可以自己定义校验的时机和内容。
nzValidateStatus: 校验状态,默认自动从nz-form-control中的NgControl获得校验状态,也可以手动指定为特定的NgControl。nzHasFeedback:用于给输入框添加反馈图标。nzSuccessTipnzWarningTipnzErrorTipnzValidatingTip:设置不同状态校验文案。
当同一种状态下存在多种提示情况时,
nzSuccessTipnzWarningTipnzErrorTipnzValidatingTip均支持传入TemplateRef<{ $implicit: FormControl }类型,可以通过模板变量导出FormControl后用于切换不同的提示信息。
import { Component } from '@angular/core';import { FormBuilder, FormControl, FormGroup, ValidationErrors, Validators } from '@angular/forms';import { Observable, Observer } from 'rxjs';@Component({selector: 'nz-demo-form-validate-reactive',template: `<form nz-form [formGroup]="validateForm" (ngSubmit)="submitForm(validateForm.value)"><nz-form-item><nz-form-label [nzSpan]="7" nzRequired>Username</nz-form-label><nz-form-control [nzSpan]="12" nzHasFeedback nzValidatingTip="Validating..." [nzErrorTip]="userErrorTpl"><input nz-input formControlName="userName" placeholder="async validate try to write JasonWood" /><ng-template #userErrorTpl let-control><ng-container *ngIf="control.hasError('required')">Please input your username!</ng-container><ng-container *ngIf="control.hasError('duplicated')">The username is redundant!</ng-container></ng-template></nz-form-control></nz-form-item><nz-form-item><nz-form-label [nzSpan]="7" nzRequired>E-mail</nz-form-label><nz-form-control [nzSpan]="12" nzHasFeedback [nzErrorTip]="emailErrorTpl"><input nz-input formControlName="email" placeholder="email" type="email" /><ng-template #emailErrorTpl let-control><ng-container *ngIf="control.hasError('email')">The input is not valid E-mail!</ng-container><ng-container *ngIf="control.hasError('required')">Please input your E-mail!</ng-container></ng-template></nz-form-control></nz-form-item><nz-form-item><nz-form-label [nzSpan]="7" nzRequired>Password</nz-form-label><div><nz-form-control [nzSpan]="12" nzHasFeedback nzErrorTip="Please input your password!"><input nz-input type="password" formControlName="password" (ngModelChange)="validateConfirmPassword()" /></nz-form-control></div></nz-form-item><nz-form-item><nz-form-label [nzSpan]="7" nzRequired>Confirm Password</nz-form-label><nz-form-control [nzSpan]="12" nzHasFeedback [nzErrorTip]="passwordErrorTpl"><input nz-input type="password" formControlName="confirm" placeholder="confirm your password" /><ng-template #passwordErrorTpl let-control><ng-container *ngIf="control.hasError('required')">Please confirm your password!</ng-container><ng-container *ngIf="control.hasError('confirm')">Password is inconsistent!</ng-container></ng-template></nz-form-control></nz-form-item><nz-form-item><nz-form-label [nzSpan]="7" nzRequired>Comment</nz-form-label><nz-form-control [nzSpan]="12" nzErrorTip="Please write something here!"><textarea formControlName="comment" nz-input rows="2" placeholder="write any thing"></textarea></nz-form-control></nz-form-item><nz-form-item><nz-form-control [nzOffset]="7" [nzSpan]="12"><button nz-button nzType="primary" [disabled]="!validateForm.valid">Submit</button><button nz-button (click)="resetForm($event)">Reset</button></nz-form-control></nz-form-item></form>`,styles: [`[nz-form] {max-width: 600px;}button {margin-left: 8px;}`]})export class NzDemoFormValidateReactiveComponent {validateForm: FormGroup;submitForm(value: any): void {for (const key in this.validateForm.controls) {this.validateForm.controls[key].markAsDirty();this.validateForm.controls[key].updateValueAndValidity();}console.log(value);}resetForm(e: MouseEvent): void {e.preventDefault();this.validateForm.reset();for (const key in this.validateForm.controls) {this.validateForm.controls[key].markAsPristine();this.validateForm.controls[key].updateValueAndValidity();}}validateConfirmPassword(): void {setTimeout(() => this.validateForm.controls.confirm.updateValueAndValidity());}userNameAsyncValidator = (control: FormControl) =>new Observable((observer: Observer<ValidationErrors | null>) => {setTimeout(() => {if (control.value === 'JasonWood') {// you have to return `{error: true}` to mark it as an error eventobserver.next({ error: true, duplicated: true });} else {observer.next(null);}observer.complete();}, 1000);});confirmValidator = (control: FormControl): { [s: string]: boolean } => {if (!control.value) {return { error: true, required: true };} else if (control.value !== this.validateForm.controls.password.value) {return { confirm: true, error: true };}return {};};constructor(private fb: FormBuilder) {this.validateForm = this.fb.group({userName: ['', [Validators.required], [this.userNameAsyncValidator]],email: ['', [Validators.email, Validators.required]],password: ['', [Validators.required]],confirm: ['', [this.confirmValidator]],comment: ['', [Validators.required]]});}}

模板驱动表单验证
当使用模板驱动表单时,模板可以根据模板设定自动进行校验。
nzHasFeedback:用于给输入框添加反馈图标。nzSuccessTipnzWarningTipnzErrorTipnzValidatingTip:设置不同状态校验文案。
当同一种状态下存在多种提示情况时,
nzSuccessTipnzWarningTipnzErrorTipnzValidatingTip均支持传入TemplateRef<{ $implicit: NgModel }类型,可以通过模板变量导出NgModel后用于切换不同的提示信息。
import { Component } from '@angular/core';@Component({selector: 'nz-demo-form-validate-template',template: `<form nz-form><nz-form-item><nz-form-label [nzSpan]="5">Required</nz-form-label><nz-form-control nzHasFeedback [nzSpan]="12" nzErrorTip="Input is required"><input nz-input [ngModel]="'Required Input'" name="required" required /></nz-form-control></nz-form-item><nz-form-item><nz-form-label [nzSpan]="5">MaxLength</nz-form-label><nz-form-control nzHasFeedback [nzSpan]="12" nzErrorTip="MaxLength is 6"><input nz-input [ngModel]="'MaxLength is 6'" name="maxlength" maxlength="6" /></nz-form-control></nz-form-item><nz-form-item><nz-form-label [nzSpan]="5">MinLength</nz-form-label><nz-form-control nzHasFeedback [nzSpan]="12" nzErrorTip="MinLength is 6"><input nz-input [ngModel]="'MinLength is 6'" name="minlength" minlength="6" /></nz-form-control></nz-form-item><nz-form-item><nz-form-label [nzSpan]="5">Email</nz-form-label><nz-form-control nzHasFeedback [nzSpan]="12" nzErrorTip="Email is not valid"><input nz-input [ngModel]="'Input Email'" name="email" email /></nz-form-control></nz-form-item><nz-form-item><nz-form-label [nzSpan]="5">Pattern</nz-form-label><nz-form-control nzHasFeedback [nzSpan]="12" nzErrorTip="Pattern not match"><input nz-input [ngModel]="'Match pattern'" name="pattern" pattern=".{3,}" /></nz-form-control></nz-form-item><nz-form-item><nz-form-label [nzSpan]="5">Mix</nz-form-label><nz-form-control nzHasFeedback [nzSpan]="12" [nzErrorTip]="combineTpl"><inputnz-input[ngModel]="'MaxLength is 12 and MinLength is 6'"name="mix"minlength="6"maxlength="12"required/><ng-template #combineTpl let-control><ng-container *ngIf="control.hasError('maxlength')">MaxLength is 12</ng-container><ng-container *ngIf="control.hasError('minlength')">MinLength is 6</ng-container><ng-container *ngIf="control.hasError('required')">Input is required</ng-container></ng-template></nz-form-control></nz-form-item></form>`,styles: [`[nz-form] {max-width: 600px;}`]})export class NzDemoFormValidateTemplateComponent {}

手动指定表单状态
用户可以在通过 nz-form-control 的 nzValidateStatus 属性直接设定表单的状态。
nzValidateStatus: 校验状态,可选 'success', 'warning', 'error', 'validating'。nzHasFeedback:用于给输入框添加反馈图标。nzSuccessTipnzWarningTipnzErrorTipnzValidatingTip:设置不同状态校验文案。
import { Component } from '@angular/core';@Component({selector: 'nz-demo-form-validate-static',template: `<form nz-form><nz-form-item><nz-form-label [nzSpan]="5">Fail</nz-form-label><nz-form-controlnzValidateStatus="error"[nzSpan]="12"nzErrorTip="Should be combination of numbers & alphabets"><input nz-input [ngModel]="'unavailable choice'" name="errorValid" /></nz-form-control></nz-form-item><nz-form-item><nz-form-label [nzSpan]="5">Warning</nz-form-label><nz-form-control nzValidateStatus="warning" [nzSpan]="12"><input nz-input [ngModel]="'Warning'" name="warningValid" /></nz-form-control></nz-form-item><nz-form-item><nz-form-label [nzSpan]="5">Validating</nz-form-label><nz-form-control[nzSpan]="12"nzValidateStatus="validating"nzHasFeedbacknzValidatingTip="I'm validating the content"><input nz-input [ngModel]="'The content is being validated'" name="validating" /></nz-form-control></nz-form-item><nz-form-item><nz-form-label [nzSpan]="5">Success</nz-form-label><nz-form-control [nzSpan]="12" nzValidateStatus="success" nzHasFeedback><input nz-input [ngModel]="'The content'" name="successValid" /></nz-form-control></nz-form-item><nz-form-item><nz-form-label [nzSpan]="5">Warning</nz-form-label><nz-form-control[nzSpan]="12"nzValidateStatus="warning"nzHasFeedbacknzWarningTip="Should be combination of numbers & alphabets"><input nz-input [ngModel]="'Warning'" name="warningHighValid" /></nz-form-control></nz-form-item><nz-form-item><nz-form-label [nzSpan]="5">Fail</nz-form-label><nz-form-control[nzSpan]="12"nzValidateStatus="error"nzHasFeedbacknzErrorTip="Should be combination of numbers & alphabets"><input nz-input [ngModel]="'unavailable choice'" name="invalidValid" /></nz-form-control></nz-form-item><nz-form-item><nz-form-label [nzSpan]="5">Success</nz-form-label><nz-form-control [nzSpan]="12" nzValidateStatus="success" nzHasFeedback><nz-date-picker name="date-picker-success"></nz-date-picker></nz-form-control></nz-form-item><nz-form-item><nz-form-label [nzSpan]="5">Warning</nz-form-label><nz-form-control [nzSpan]="12" nzValidateStatus="warning" nzHasFeedback><nz-time-picker name="time-picker-warning"></nz-time-picker></nz-form-control></nz-form-item><nz-form-item><nz-form-label [nzSpan]="5">Error</nz-form-label><nz-form-control [nzSpan]="12" nzValidateStatus="error" nzHasFeedback><nz-select name="select-error" [ngModel]="'Option 1'"><nz-option nzValue="Option 1" nzLabel="Option 1"></nz-option><nz-option nzValue="Option 2" nzLabel="Option 2"></nz-option></nz-select></nz-form-control></nz-form-item><nz-form-item><nz-form-label [nzSpan]="5">Validating</nz-form-label><nz-form-control [nzSpan]="12" nzValidateStatus="validating" nzHasFeedback><nz-select name="select-validate" [ngModel]="'Option 2'"><nz-option nzValue="Option 1" nzLabel="Option 1"></nz-option><nz-option nzValue="Option 2" nzLabel="Option 2"></nz-option></nz-select></nz-form-control></nz-form-item><nz-form-item><nz-form-label [nzSpan]="5">Success</nz-form-label><nz-form-control [nzSpan]="12" nzValidateStatus="success" nzHasFeedback><nz-input-number name="inputnumber-success" style="width:100%"></nz-input-number></nz-form-control></nz-form-item></form>`,styles: [`[nz-form] {max-width: 600px;}nz-date-picker ::ng-deep .ant-calendar-picker {width: 100%;}nz-date-picker,nz-time-picker {width: 100%;}`]})export class NzDemoFormValidateStaticComponent {}

表单联动
使用 setValue 来动态设置其他控件的值。
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
@Component({
selector: 'nz-demo-form-coordinated',
template: `
<form nz-form [formGroup]="validateForm" (ngSubmit)="submitForm()">
<nz-form-item>
<nz-form-label [nzSpan]="5" nzRequired nzFor="note">Note</nz-form-label>
<nz-form-control [nzSpan]="12" nzErrorTip="Please input your username!">
<input id="note" type="text" nz-input formControlName="note" />
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label [nzSpan]="5" nzFor="gender" nzRequired>Gender</nz-form-label>
<nz-form-control [nzSpan]="12" nzErrorTip="Please select your gender!">
<nz-select
id="gender"
formControlName="gender"
nzPlaceHolder="Select a option and change input text above"
(ngModelChange)="genderChange($event)"
>
<nz-option nzValue="male" nzLabel="male"></nz-option>
<nz-option nzValue="female" nzLabel="female"></nz-option>
</nz-select>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-control [nzSpan]="12" [nzOffset]="5">
<button nz-button nzType="primary">Submit</button>
</nz-form-control>
</nz-form-item>
</form>
`,
styles: [
`
[nz-form] {
max-width: 600px;
}
`
]
})
export class NzDemoFormCoordinatedComponent implements OnInit {
validateForm: FormGroup;
submitForm(): void {
for (const i in this.validateForm.controls) {
this.validateForm.controls[i].markAsDirty();
this.validateForm.controls[i].updateValueAndValidity();
}
}
genderChange(value: string): void {
this.validateForm.get('note')!.setValue(value === 'male' ? 'Hi, man!' : 'Hi, lady!');
}
constructor(private fb: FormBuilder) {}
ngOnInit(): void {
this.validateForm = this.fb.group({
note: [null, [Validators.required]],
gender: [null, [Validators.required]]
});
}
}

表单布局
表单有三种布局。
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
@Component({
selector: 'nz-demo-form-layout',
template: `
<form
nz-form
[nzLayout]="validateForm.get('formLayout')?.value"
[formGroup]="validateForm"
(ngSubmit)="submitForm()"
>
<nz-form-item>
<nz-form-label [nzSpan]="isHorizontal ? 4 : null">Form Layout</nz-form-label>
<nz-form-control [nzSpan]="isHorizontal ? 14 : null">
<nz-radio-group formControlName="formLayout">
<label nz-radio-button [nzValue]="'horizontal'">Horizontal</label>
<label nz-radio-button [nzValue]="'vertical'">Vertical</label>
<label nz-radio-button [nzValue]="'inline'">Inline</label>
</nz-radio-group>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label [nzSpan]="isHorizontal ? 4 : null">Field A</nz-form-label>
<nz-form-control [nzSpan]="isHorizontal ? 14 : null" nzErrorTip="Please input your username!">
<input nz-input formControlName="fieldA" placeholder="input placeholder" />
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label [nzSpan]="isHorizontal ? 4 : null">Field B</nz-form-label>
<nz-form-control [nzSpan]="isHorizontal ? 14 : null" nzErrorTip="Please input your Password!">
<input nz-input formControlName="filedB" placeholder="input placeholder" />
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-control [nzSpan]="isHorizontal ? 14 : null" [nzOffset]="isHorizontal ? 4 : null">
<button nz-button nzType="primary">Submit</button>
</nz-form-control>
</nz-form-item>
</form>
`,
styles: [
`
[nz-form]:not(.ant-form-inline):not(.ant-form-vertical) {
max-width: 600px;
}
`
]
})
export class NzDemoFormLayoutComponent implements OnInit {
validateForm: FormGroup;
submitForm(): void {
for (const i in this.validateForm.controls) {
this.validateForm.controls[i].markAsDirty();
this.validateForm.controls[i].updateValueAndValidity();
}
}
get isHorizontal(): boolean {
return this.validateForm.controls.formLayout && this.validateForm.controls.formLayout.value === 'horizontal';
}
constructor(private fb: FormBuilder) {}
ngOnInit(): void {
this.validateForm = this.fb.group({
formLayout: ['horizontal'],
fieldA: [null, [Validators.required]],
filedB: [null, [Validators.required]]
});
}
}

动态校验规则
根据不同情况执行不同的校验规则。
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
@Component({
selector: 'nz-demo-form-dynamic-rule',
template: `
<form nz-form [formGroup]="validateForm" (ngSubmit)="submitForm()">
<nz-form-item>
<nz-form-label [nzSpan]="4" nzRequired nzFor="name">Name</nz-form-label>
<nz-form-control [nzSpan]="8" nzErrorTip="Please input your name">
<input type="text" nz-input formControlName="name" placeholder="Please input your name" />
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label [nzSpan]="4" nzFor="nickname" [nzRequired]="validateForm.get('required')?.value"
>Nickname</nz-form-label
>
<nz-form-control [nzSpan]="8" nzErrorTip="Please input your nickname">
<input type="text" nz-input formControlName="nickname" placeholder="Please input your nickname" />
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-control [nzSpan]="8" [nzOffset]="4">
<label nz-checkbox formControlName="required" (ngModelChange)="requiredChange($event)"
>Nickname is required</label
>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-control [nzSpan]="8" [nzOffset]="4">
<button nz-button nzType="primary">Check</button>
</nz-form-control>
</nz-form-item>
</form>
`
})
export class NzDemoFormDynamicRuleComponent implements OnInit {
validateForm: FormGroup;
submitForm(): void {
for (const i in this.validateForm.controls) {
this.validateForm.controls[i].markAsDirty();
this.validateForm.controls[i].updateValueAndValidity();
}
}
requiredChange(required: boolean): void {
if (!required) {
this.validateForm.get('nickname')!.clearValidators();
this.validateForm.get('nickname')!.markAsPristine();
} else {
this.validateForm.get('nickname')!.setValidators(Validators.required);
this.validateForm.get('nickname')!.markAsDirty();
}
this.validateForm.get('nickname')!.updateValueAndValidity();
}
constructor(private fb: FormBuilder) {}
ngOnInit(): void {
this.validateForm = this.fb.group({
name: [null, [Validators.required]],
nickname: [null],
required: [false]
});
}
}
API
[nz-form]directive
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
[nzLayout] | 表单布局 | 'horizontal' | 'vertical' | 'inline' | 'horizontal' |
[nzNoColon] | 配置 nz-form-label 的 [nzNoColon] 的默认值 | boolean | false |
nz-form-itemcomponent
表单项用于区分表单中不同的区域,包含表单域和表单标签(可选)。
所有 nz-row 的参数在
nz-form-item上均可直接使用。
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
[nzFlex] | 是否Flex布局 | boolean | false |
nz-form-labelcomponent
用于标示当前表单项的内容,可选。
所有 nz-col 的参数在
nz-form-label上均可直接使用。
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
[nzRequired] | 当前项是否为必填,仅影响样式 | boolean | false |
[nzNoColon] | 是否不显示 label 后面的冒号 | boolean | false |
[nzFor] | label 标签的 for 属性 | string | - |
nz-form-controlcomponent
注意:由于 Angular Form 目前提供的状态变更订阅不完整。手动更改表单状态时,例如
markAsDirty后,需要执行updateValueAndValidity通知nz-form-control进行状态变更。
表单一定会包含表单域,表单域可以是输入控件,标准表单域,标签,下拉菜单,文本域等。
所有 nz-col 的参数在
nz-form-control上均可直接使用。
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
[nzValidateStatus] | 会根据传入的 FormControl 或 NgModel 自动生成校验状态,也可以直接指定状态,不传入时默认值为 nz-form-control 中包裹的第一个 FormControl 或 NgModel | 'success' | 'warning' | 'error' | 'validating' | FormControl | NgModel | nz-form-control 中包裹的第一个 FormControl 或 NgModel |
[nzHasFeedback] | 配合 nzValidateStatus 属性使用,展示校验状态图标 | boolean | false |
[nzExtra] | 用于显示表单额外提示信息 | string | TemplateRef<void> | - |
[nzSuccessTip] | 校验状态 success 时提示信息 | string | TemplateRef<{ $implicit: FormControl | NgModel }> | - |
[nzWarningTip] | 校验状态 warning 时提示信息 | string | TemplateRef<{ $implicit: FormControl | NgModel }> | - |
[nzErrorTip] | 校验状态 error 时提示信息 | string | TemplateRef<{ $implicit: FormControl | NgModel }> | - |
[nzValidatingTip] | 正在校验时提示信息 | string | TemplateRef<{ $implicit: FormControl | NgModel }> | - |
nz-form-splitcomponent
用于显示分隔符 -
nz-form-textcomponent
在 nz-form-control 中直接显示文本
