Form表单

具有数据收集、校验和提交功能的表单,包含复选框、单选框、输入框、下拉选择框等元素。

该组件需要与 Angular表单 结合使用,开发者根据需要可以自由选择 响应式表单模板驱动表单.

使用该组件前请确保您已经阅读并掌握了 Forms 的使用方式。

表单

我们提供了以下三种排列方式:

  • 水平排列:标签和表单控件水平排列;(默认)
  • 垂直排列:标签和表单控件上下垂直排列;
  • 行内排列:表单项水平行内排列。

表单项 nz-form-item

表单项用于区分表单中不同的区域,包含表单域和表单标签(可选)。

表单标签 nz-form-label

用于标示当前表单项的内容,可选。

表单域 nz-form-control

表单一定会包含表单域,表单域可以是输入控件,标准表单域,标签,下拉菜单,文本域等。

  1. <form nz-form>
  2. <nz-form-item>
  3. <nz-form-label [nzSpan]="6" nzFor="email">E-mail</nz-form-label>
  4. <nz-form-control [nzSpan]="14">
  5. <input nz-input name="email" type="email" id="email">
  6. </nz-form-control>
  7. </nz-form-item >
  8. </form>

代码演示

Form表单 - 图1

水平登录栏

水平登录栏,常用在顶部导航栏中。

  1. import { Component, OnInit } from '@angular/core';
  2. import { FormBuilder, FormGroup, Validators } from '@angular/forms';
  3. @Component({
  4. selector: 'nz-demo-form-horizontal-login',
  5. template: `
  6. <form nz-form [nzLayout]="'inline'" [formGroup]="validateForm" (ngSubmit)="submitForm()">
  7. <nz-form-item>
  8. <nz-form-control>
  9. <nz-input-group [nzPrefix]="prefixUser">
  10. <input formControlName="userName" nz-input placeholder="Username" />
  11. </nz-input-group>
  12. <nz-form-explain *ngIf="validateForm.get('userName')?.dirty && validateForm.get('userName')?.errors"
  13. >Please input your username!</nz-form-explain
  14. >
  15. </nz-form-control>
  16. </nz-form-item>
  17. <nz-form-item>
  18. <nz-form-control>
  19. <nz-input-group [nzPrefix]="prefixLock">
  20. <input formControlName="password" nz-input type="password" placeholder="Password" />
  21. </nz-input-group>
  22. <nz-form-explain *ngIf="validateForm.get('password')?.dirty && validateForm.get('password')?.errors"
  23. >Please input your Password!</nz-form-explain
  24. >
  25. </nz-form-control>
  26. </nz-form-item>
  27. <nz-form-item>
  28. <nz-form-control>
  29. <button nz-button nzType="primary" [disabled]="!validateForm.valid">Log in</button>
  30. </nz-form-control>
  31. </nz-form-item>
  32. </form>
  33. <ng-template #prefixUser><i nz-icon type="user"></i></ng-template>
  34. <ng-template #prefixLock><i nz-icon type="lock"></i></ng-template>
  35. `
  36. })
  37. export class NzDemoFormHorizontalLoginComponent implements OnInit {
  38. validateForm: FormGroup;
  39. submitForm(): void {
  40. for (const i in this.validateForm.controls) {
  41. this.validateForm.controls[i].markAsDirty();
  42. this.validateForm.controls[i].updateValueAndValidity();
  43. }
  44. }
  45. constructor(private fb: FormBuilder) {}
  46. ngOnInit(): void {
  47. this.validateForm = this.fb.group({
  48. userName: [null, [Validators.required]],
  49. password: [null, [Validators.required]],
  50. remember: [true]
  51. });
  52. }
  53. }

Form表单 - 图2

登录框

普通的登录框,可以容纳更多的元素。

  1. import { Component, OnInit } from '@angular/core';
  2. import { FormBuilder, FormGroup, Validators } from '@angular/forms';
  3. @Component({
  4. selector: 'nz-demo-form-normal-login',
  5. template: `
  6. <form nz-form [formGroup]="validateForm" class="login-form" (ngSubmit)="submitForm()">
  7. <nz-form-item>
  8. <nz-form-control>
  9. <nz-input-group [nzPrefix]="prefixUser">
  10. <input type="text" nz-input formControlName="userName" placeholder="Username" />
  11. </nz-input-group>
  12. <nz-form-explain *ngIf="validateForm.get('userName')?.dirty && validateForm.get('userName')?.errors"
  13. >Please input your username!</nz-form-explain
  14. >
  15. </nz-form-control>
  16. </nz-form-item>
  17. <nz-form-item>
  18. <nz-form-control>
  19. <nz-input-group [nzPrefix]="prefixLock">
  20. <input type="password" nz-input formControlName="password" placeholder="Password" />
  21. </nz-input-group>
  22. <nz-form-explain *ngIf="validateForm.get('password')?.dirty && validateForm.get('password')?.errors"
  23. >Please input your Password!</nz-form-explain
  24. >
  25. </nz-form-control>
  26. </nz-form-item>
  27. <nz-form-item>
  28. <nz-form-control>
  29. <label nz-checkbox formControlName="remember">
  30. <span>Remember me</span>
  31. </label>
  32. <a class="login-form-forgot" class="login-form-forgot">Forgot password</a>
  33. <button nz-button class="login-form-button" [nzType]="'primary'">Log in</button>
  34. Or
  35. <a href="">register now!</a>
  36. </nz-form-control>
  37. </nz-form-item>
  38. </form>
  39. <ng-template #prefixUser><i nz-icon type="user"></i></ng-template>
  40. <ng-template #prefixLock><i nz-icon type="lock"></i></ng-template>
  41. `,
  42. styles: [
  43. `
  44. .login-form {
  45. max-width: 300px;
  46. }
  47. .login-form-forgot {
  48. float: right;
  49. }
  50. .login-form-button {
  51. width: 100%;
  52. }
  53. `
  54. ]
  55. })
  56. export class NzDemoFormNormalLoginComponent implements OnInit {
  57. validateForm: FormGroup;
  58. submitForm(): void {
  59. for (const i in this.validateForm.controls) {
  60. this.validateForm.controls[i].markAsDirty();
  61. this.validateForm.controls[i].updateValueAndValidity();
  62. }
  63. }
  64. constructor(private fb: FormBuilder) {}
  65. ngOnInit(): void {
  66. this.validateForm = this.fb.group({
  67. userName: [null, [Validators.required]],
  68. password: [null, [Validators.required]],
  69. remember: [true]
  70. });
  71. }
  72. }

Form表单 - 图3

注册新用户

用户填写必须的信息以注册新用户。

  1. import { Component, OnInit } from '@angular/core';
  2. import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
  3. @Component({
  4. selector: 'nz-demo-form-register',
  5. template: `
  6. <form nz-form [formGroup]="validateForm" (ngSubmit)="submitForm()">
  7. <nz-form-item>
  8. <nz-form-label [nzSm]="6" [nzXs]="24" nzRequired nzFor="email">E-mail</nz-form-label>
  9. <nz-form-control [nzSm]="14" [nzXs]="24">
  10. <input nz-input formControlName="email" id="email" />
  11. <nz-form-explain *ngIf="validateForm.get('email')?.dirty && validateForm.get('email')?.errors">
  12. The input is not valid E-mail!
  13. </nz-form-explain>
  14. </nz-form-control>
  15. </nz-form-item>
  16. <nz-form-item>
  17. <nz-form-label [nzSm]="6" [nzXs]="24" nzFor="password" nzRequired>Password</nz-form-label>
  18. <nz-form-control [nzSm]="14" [nzXs]="24">
  19. <input
  20. nz-input
  21. type="password"
  22. id="password"
  23. formControlName="password"
  24. (ngModelChange)="updateConfirmValidator()"
  25. />
  26. <nz-form-explain *ngIf="validateForm.get('password')?.dirty && validateForm.get('password')?.errors"
  27. >Please input your password!</nz-form-explain
  28. >
  29. </nz-form-control>
  30. </nz-form-item>
  31. <nz-form-item>
  32. <nz-form-label [nzSm]="6" [nzXs]="24" nzFor="checkPassword" nzRequired>Confirm Password</nz-form-label>
  33. <nz-form-control [nzSm]="14" [nzXs]="24">
  34. <input nz-input type="password" formControlName="checkPassword" id="checkPassword" />
  35. <nz-form-explain
  36. *ngIf="validateForm.get('checkPassword')?.dirty && validateForm.get('checkPassword')?.errors"
  37. >
  38. <ng-container *ngIf="validateForm.get('checkPassword')?.hasError('required')">
  39. Please confirm your password!
  40. </ng-container>
  41. <ng-container *ngIf="validateForm.get('checkPassword')?.hasError('confirm')">
  42. Two passwords that you enter is inconsistent!
  43. </ng-container>
  44. </nz-form-explain>
  45. </nz-form-control>
  46. </nz-form-item>
  47. <nz-form-item>
  48. <nz-form-label [nzSm]="6" [nzXs]="24" nzFor="nickname" nzRequired>
  49. <span>
  50. Nickname
  51. <i
  52. nz-icon
  53. nz-tooltip
  54. nzTitle="What do you want other to call you"
  55. type="question-circle"
  56. theme="outline"
  57. ></i>
  58. </span>
  59. </nz-form-label>
  60. <nz-form-control [nzSm]="14" [nzXs]="24">
  61. <input nz-input id="nickname" formControlName="nickname" />
  62. <nz-form-explain *ngIf="validateForm.get('nickname')?.dirty && validateForm.get('nickname')?.errors"
  63. >Please input your nickname!</nz-form-explain
  64. >
  65. </nz-form-control>
  66. </nz-form-item>
  67. <nz-form-item>
  68. <nz-form-label [nzSm]="6" [nzXs]="24" nzFor="phoneNumber" nzRequired>Phone Number</nz-form-label>
  69. <nz-form-control [nzSm]="14" [nzXs]="24" [nzValidateStatus]="validateForm.controls['phoneNumber']">
  70. <nz-input-group [nzAddOnBefore]="addOnBeforeTemplate">
  71. <ng-template #addOnBeforeTemplate>
  72. <nz-select formControlName="phoneNumberPrefix" style="width: 70px;">
  73. <nz-option nzLabel="+86" nzValue="+86"></nz-option>
  74. <nz-option nzLabel="+87" nzValue="+87"></nz-option>
  75. </nz-select>
  76. </ng-template>
  77. <input formControlName="phoneNumber" id="'phoneNumber'" nz-input />
  78. </nz-input-group>
  79. <nz-form-explain *ngIf="validateForm.get('phoneNumber')?.dirty && validateForm.get('phoneNumber')?.errors"
  80. >Please input your phone number!</nz-form-explain
  81. >
  82. </nz-form-control>
  83. </nz-form-item>
  84. <nz-form-item>
  85. <nz-form-label [nzSm]="6" [nzXs]="24" nzFor="website" nzRequired>Website</nz-form-label>
  86. <nz-form-control [nzSm]="14" [nzXs]="24">
  87. <input nz-input id="website" formControlName="website" placeholder="website" />
  88. <nz-form-explain *ngIf="validateForm.get('website')?.dirty && validateForm.get('website')?.errors"
  89. >Please input website!</nz-form-explain
  90. >
  91. </nz-form-control>
  92. </nz-form-item>
  93. <nz-form-item>
  94. <nz-form-label [nzSm]="6" [nzXs]="24" nzFor="captcha" nzRequired>Captcha</nz-form-label>
  95. <nz-form-control [nzSm]="14" [nzXs]="24">
  96. <div nz-row [nzGutter]="8">
  97. <div nz-col [nzSpan]="12">
  98. <input nz-input formControlName="captcha" id="captcha" />
  99. </div>
  100. <div nz-col [nzSpan]="12">
  101. <button nz-button (click)="getCaptcha($event)">Get captcha</button>
  102. </div>
  103. </div>
  104. <nz-form-explain *ngIf="validateForm.get('captcha')?.dirty && validateForm.get('captcha')?.errors"
  105. >Please input the captcha you got!</nz-form-explain
  106. >
  107. <nz-form-extra>We must make sure that your are a human.</nz-form-extra>
  108. </nz-form-control>
  109. </nz-form-item>
  110. <nz-form-item nz-row style="margin-bottom:8px;">
  111. <nz-form-control [nzSpan]="14" [nzOffset]="6">
  112. <label nz-checkbox formControlName="agree">
  113. <span>I have read the <a>agreement</a></span>
  114. </label>
  115. </nz-form-control>
  116. </nz-form-item>
  117. <nz-form-item nz-row style="margin-bottom:8px;">
  118. <nz-form-control [nzSpan]="14" [nzOffset]="6">
  119. <button nz-button nzType="primary">Register</button>
  120. </nz-form-control>
  121. </nz-form-item>
  122. </form>
  123. `,
  124. styles: [
  125. `
  126. [nz-form] {
  127. max-width: 600px;
  128. }
  129. `
  130. ]
  131. })
  132. export class NzDemoFormRegisterComponent implements OnInit {
  133. validateForm: FormGroup;
  134. submitForm(): void {
  135. for (const i in this.validateForm.controls) {
  136. this.validateForm.controls[i].markAsDirty();
  137. this.validateForm.controls[i].updateValueAndValidity();
  138. }
  139. }
  140. updateConfirmValidator(): void {
  141. /** wait for refresh value */
  142. Promise.resolve().then(() => this.validateForm.controls.checkPassword.updateValueAndValidity());
  143. }
  144. confirmationValidator = (control: FormControl): { [s: string]: boolean } => {
  145. if (!control.value) {
  146. return { required: true };
  147. } else if (control.value !== this.validateForm.controls.password.value) {
  148. return { confirm: true, error: true };
  149. }
  150. return {};
  151. };
  152. getCaptcha(e: MouseEvent): void {
  153. e.preventDefault();
  154. }
  155. constructor(private fb: FormBuilder) {}
  156. ngOnInit(): void {
  157. this.validateForm = this.fb.group({
  158. email: [null, [Validators.email, Validators.required]],
  159. password: [null, [Validators.required]],
  160. checkPassword: [null, [Validators.required, this.confirmationValidator]],
  161. nickname: [null, [Validators.required]],
  162. phoneNumberPrefix: ['+86'],
  163. phoneNumber: [null, [Validators.required]],
  164. website: [null, [Validators.required]],
  165. captcha: [null, [Validators.required]],
  166. agree: [false]
  167. });
  168. }
  169. }

Form表单 - 图4

高级搜索

三列栅格式的表单排列方式,常用于数据表格的高级搜索。

有部分定制的样式代码,由于输入标签长度不确定,需要根据具体情况自行调整。

  1. import { Component, OnInit } from '@angular/core';
  2. import { FormBuilder, FormControl, FormGroup } from '@angular/forms';
  3. @Component({
  4. selector: 'nz-demo-form-advanced-search',
  5. template: `
  6. <form nz-form [formGroup]="validateForm" class="ant-advanced-search-form">
  7. <div nz-row [nzGutter]="24">
  8. <div nz-col [nzSpan]="8" *ngFor="let control of controlArray" [style.display]="control.show ? 'block' : 'none'">
  9. <nz-form-item nzFlex>
  10. <nz-form-label [nzFor]="'field' + control.index">Field {{ control.index }}</nz-form-label>
  11. <nz-form-control>
  12. <input
  13. nz-input
  14. placeholder="placeholder"
  15. [formControlName]="'field' + control.index"
  16. [attr.id]="'field' + control.index"
  17. />
  18. </nz-form-control>
  19. </nz-form-item>
  20. </div>
  21. </div>
  22. <div nz-row>
  23. <div nz-col [nzSpan]="24" style="text-align: right;">
  24. <button nz-button [nzType]="'primary'">Search</button>
  25. <button nz-button (click)="resetForm()">Clear</button>
  26. <a style="margin-left:8px;font-size:12px;" (click)="toggleCollapse()">
  27. Collapse
  28. <i nz-icon [type]="isCollapse ? 'down' : 'up'"></i>
  29. </a>
  30. </div>
  31. </div>
  32. </form>
  33. <div class="search-result-list">
  34. Search Result List
  35. </div>
  36. `,
  37. styles: [
  38. `
  39. .ant-advanced-search-form {
  40. padding: 24px;
  41. background: #fbfbfb;
  42. border: 1px solid #d9d9d9;
  43. border-radius: 6px;
  44. }
  45. .search-result-list {
  46. margin-top: 16px;
  47. border: 1px dashed #e9e9e9;
  48. border-radius: 6px;
  49. background-color: #fafafa;
  50. min-height: 200px;
  51. text-align: center;
  52. padding-top: 80px;
  53. }
  54. [nz-form-label] {
  55. overflow: visible;
  56. }
  57. button {
  58. margin-left: 8px;
  59. }
  60. `
  61. ]
  62. })
  63. export class NzDemoFormAdvancedSearchComponent implements OnInit {
  64. validateForm: FormGroup;
  65. controlArray: any[] = [];
  66. isCollapse = true;
  67. toggleCollapse(): void {
  68. this.isCollapse = !this.isCollapse;
  69. this.controlArray.forEach((c, index) => {
  70. c.show = this.isCollapse ? index < 6 : true;
  71. });
  72. }
  73. resetForm(): void {
  74. this.validateForm.reset();
  75. }
  76. constructor(private fb: FormBuilder) {}
  77. ngOnInit(): void {
  78. this.validateForm = this.fb.group({});
  79. for (let i = 0; i < 10; i++) {
  80. this.controlArray.push({ index: i, show: i < 6 });
  81. this.validateForm.addControl(`field${i}`, new FormControl());
  82. }
  83. }
  84. }

Form表单 - 图5

动态增减表单项

动态增加、减少表单项。

  1. import { Component, OnInit } from '@angular/core';
  2. import { AbstractControl, FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
  3. @Component({
  4. selector: 'nz-demo-form-dynamic-form-item',
  5. template: `
  6. <form nz-form [formGroup]="validateForm" (ngSubmit)="submitForm()">
  7. <nz-form-item *ngFor="let control of controlArray; let i = index">
  8. <nz-form-label [nzXs]="24" [nzSm]="4" *ngIf="i == 0" [nzFor]="control.controlInstance"
  9. >Passengers</nz-form-label
  10. >
  11. <nz-form-control [nzXs]="24" [nzSm]="20" [nzOffset]="i == 0 ? 0 : 4">
  12. <input
  13. nz-input
  14. style="width: 60%; margin-right:8px;"
  15. placeholder="placeholder"
  16. [attr.id]="control.id"
  17. [formControlName]="control.controlInstance"
  18. />
  19. <i nz-icon type="minus-circle-o" class="dynamic-delete-button" (click)="removeField(control, $event)"></i>
  20. <nz-form-explain
  21. *ngIf="
  22. getFormControl(control.controlInstance)?.dirty &&
  23. getFormControl(control.controlInstance)?.hasError('required')
  24. "
  25. >
  26. Please input passenger's name or delete this field.
  27. </nz-form-explain>
  28. </nz-form-control>
  29. </nz-form-item>
  30. <nz-form-item>
  31. <nz-form-control [nzXs]="{ span: 24, offset: 0 }" [nzSm]="{ span: 20, offset: 4 }">
  32. <button nz-button nzType="dashed" style="width:60%" (click)="addField($event)">
  33. <i nz-icon type="plus"></i> Add field
  34. </button>
  35. </nz-form-control>
  36. </nz-form-item>
  37. <nz-form-item>
  38. <nz-form-control [nzXs]="{ span: 24, offset: 0 }" [nzSm]="{ span: 20, offset: 4 }">
  39. <button nz-button nzType="primary">Submit</button>
  40. </nz-form-control>
  41. </nz-form-item>
  42. </form>
  43. `,
  44. styles: [
  45. `
  46. .dynamic-delete-button {
  47. cursor: pointer;
  48. position: relative;
  49. top: 4px;
  50. font-size: 24px;
  51. color: #999;
  52. transition: all 0.3s;
  53. }
  54. .dynamic-delete-button:hover {
  55. color: #777;
  56. }
  57. [nz-form] {
  58. max-width: 600px;
  59. }
  60. `
  61. ]
  62. })
  63. export class NzDemoFormDynamicFormItemComponent implements OnInit {
  64. validateForm: FormGroup;
  65. controlArray: Array<{ id: number; controlInstance: string }> = [];
  66. addField(e?: MouseEvent): void {
  67. if (e) {
  68. e.preventDefault();
  69. }
  70. const id = this.controlArray.length > 0 ? this.controlArray[this.controlArray.length - 1].id + 1 : 0;
  71. const control = {
  72. id,
  73. controlInstance: `passenger${id}`
  74. };
  75. const index = this.controlArray.push(control);
  76. console.log(this.controlArray[this.controlArray.length - 1]);
  77. this.validateForm.addControl(
  78. this.controlArray[index - 1].controlInstance,
  79. new FormControl(null, Validators.required)
  80. );
  81. }
  82. removeField(i: { id: number; controlInstance: string }, e: MouseEvent): void {
  83. e.preventDefault();
  84. if (this.controlArray.length > 1) {
  85. const index = this.controlArray.indexOf(i);
  86. this.controlArray.splice(index, 1);
  87. console.log(this.controlArray);
  88. this.validateForm.removeControl(i.controlInstance);
  89. }
  90. }
  91. getFormControl(name: string): AbstractControl {
  92. return this.validateForm.controls[name];
  93. }
  94. submitForm(): void {
  95. for (const i in this.validateForm.controls) {
  96. this.validateForm.controls[i].markAsDirty();
  97. this.validateForm.controls[i].updateValueAndValidity();
  98. }
  99. console.log(this.validateForm.value);
  100. }
  101. constructor(private fb: FormBuilder) {}
  102. ngOnInit(): void {
  103. this.validateForm = this.fb.group({});
  104. this.addField();
  105. }
  106. }

Form表单 - 图6

时间类控件

时间类组件的输入和输出类型均为 Date 类型,可以通过 date-fns 工具库进行进一步的处理。

  1. import { Component, OnInit } from '@angular/core';
  2. import { FormBuilder, FormGroup } from '@angular/forms';
  3. @Component({
  4. selector: 'nz-demo-form-time-related-controls',
  5. template: `
  6. <form nz-form [formGroup]="validateForm" (ngSubmit)="submitForm()">
  7. <nz-form-item>
  8. <nz-form-label [nzSm]="8" [nzXs]="24" nzRequired>DatePicker</nz-form-label>
  9. <nz-form-control [nzSm]="16" [nzXs]="24">
  10. <nz-date-picker formControlName="datePicker"></nz-date-picker>
  11. </nz-form-control>
  12. </nz-form-item>
  13. <nz-form-item>
  14. <nz-form-label [nzSm]="8" [nzXs]="24" nzRequired>DatePicker[ShowTime]</nz-form-label>
  15. <nz-form-control [nzSm]="16" [nzXs]="24">
  16. <nz-date-picker nzShowTime formControlName="datePickerTime"></nz-date-picker>
  17. </nz-form-control>
  18. </nz-form-item>
  19. <nz-form-item>
  20. <nz-form-label [nzSm]="8" [nzXs]="24" nzRequired>MonthPicker</nz-form-label>
  21. <nz-form-control [nzSm]="16" [nzXs]="24">
  22. <nz-month-picker formControlName="monthPicker"></nz-month-picker>
  23. </nz-form-control>
  24. </nz-form-item>
  25. <nz-form-item>
  26. <nz-form-label [nzSm]="8" [nzXs]="24" nzRequired>RangePicker</nz-form-label>
  27. <nz-form-control [nzSm]="16" [nzXs]="24">
  28. <nz-range-picker formControlName="rangePicker"></nz-range-picker>
  29. </nz-form-control>
  30. </nz-form-item>
  31. <nz-form-item>
  32. <nz-form-label [nzSm]="8" [nzXs]="24" nzRequired>RangePicker[showTime]</nz-form-label>
  33. <nz-form-control [nzSm]="16" [nzXs]="24">
  34. <nz-range-picker nzShowTime formControlName="rangePickerTime"></nz-range-picker>
  35. </nz-form-control>
  36. </nz-form-item>
  37. <nz-form-item>
  38. <nz-form-label [nzSm]="8" [nzXs]="24" nzRequired>TimePicker</nz-form-label>
  39. <nz-form-control [nzSm]="16" [nzXs]="24">
  40. <nz-time-picker formControlName="timePicker"></nz-time-picker>
  41. </nz-form-control>
  42. </nz-form-item>
  43. <nz-form-item>
  44. <nz-form-control [nzXs]="{ span: 24, offset: 0 }" [nzSm]="{ span: 16, offset: 8 }">
  45. <button nz-button nzType="primary">Submit</button>
  46. </nz-form-control>
  47. </nz-form-item>
  48. </form>
  49. `,
  50. styles: [
  51. `
  52. form {
  53. max-width: 600px;
  54. }
  55. `
  56. ]
  57. })
  58. export class NzDemoFormTimeRelatedControlsComponent implements OnInit {
  59. validateForm: FormGroup;
  60. submitForm(): void {
  61. console.log(this.validateForm.value);
  62. }
  63. constructor(private fb: FormBuilder) {}
  64. ngOnInit(): void {
  65. this.validateForm = this.fb.group({
  66. datePicker: [null],
  67. datePickerTime: [null],
  68. monthPicker: [null],
  69. rangePicker: [[]],
  70. rangePickerTime: [[]],
  71. timePicker: [null]
  72. });
  73. }
  74. }

Form表单 - 图7

响应式表单验证

我们在 nz-form-control 上 提供了 nzValidateStatusnzHasFeedback 等属性,当使用响应式表单时,可以自己定义校验的时机和内容。

  • nzValidateStatus: 校验状态,默认自动从 nz-form-control 中的 NgControl 获得校验状态,也可以手动指定为特定的 NgControl
  • nzHasFeedback:用于给输入框添加反馈图标。
  • nz-form-explain:设置校验文案。
  1. import { Component } from '@angular/core';
  2. import { FormBuilder, FormControl, FormGroup, ValidationErrors, Validators } from '@angular/forms';
  3. import { Observable, Observer } from 'rxjs';
  4. @Component({
  5. selector: 'nz-demo-form-validate-reactive',
  6. template: `
  7. <form nz-form [formGroup]="validateForm" (ngSubmit)="submitForm($event, validateForm.value)">
  8. <nz-form-item>
  9. <nz-form-label [nzSpan]="7" nzRequired>Username</nz-form-label>
  10. <nz-form-control [nzSpan]="12" nzHasFeedback>
  11. <input nz-input formControlName="userName" placeholder="async validate try to write JasonWood" />
  12. <nz-form-explain
  13. *ngIf="
  14. (validateForm.get('userName')?.dirty && validateForm.get('userName')?.errors) ||
  15. validateForm.get('userName')?.pending
  16. "
  17. >
  18. <ng-container *ngIf="validateForm.get('userName')?.hasError('required')">
  19. Please input your username!
  20. </ng-container>
  21. <ng-container *ngIf="validateForm.get('userName')?.hasError('duplicated')">
  22. The username is redundant!
  23. </ng-container>
  24. <ng-container *ngIf="validateForm.get('userName')?.pending">
  25. Validating...
  26. </ng-container>
  27. </nz-form-explain>
  28. </nz-form-control>
  29. </nz-form-item>
  30. <nz-form-item>
  31. <nz-form-label [nzSpan]="7" nzRequired>E-mail</nz-form-label>
  32. <nz-form-control [nzSpan]="12" nzHasFeedback>
  33. <input nz-input formControlName="email" placeholder="email" type="email" />
  34. <nz-form-explain *ngIf="validateForm.get('email')?.dirty && validateForm.get('email')?.errors">
  35. <ng-container *ngIf="validateForm.get('email')?.hasError('email')">
  36. The input is not valid E-mail!
  37. </ng-container>
  38. <ng-container *ngIf="validateForm.get('email')?.hasError('required')">
  39. Please input your E-mail!
  40. </ng-container>
  41. </nz-form-explain>
  42. </nz-form-control>
  43. </nz-form-item>
  44. <nz-form-item>
  45. <nz-form-label [nzSpan]="7" nzRequired>Password</nz-form-label>
  46. <div>
  47. <nz-form-control [nzSpan]="12" nzHasFeedback>
  48. <input nz-input type="password" formControlName="password" (ngModelChange)="validateConfirmPassword()" />
  49. <nz-form-explain
  50. *ngIf="validateForm.get('password')?.dirty && validateForm.get('password')?.hasError('required')"
  51. >Please input your password!</nz-form-explain
  52. >
  53. </nz-form-control>
  54. </div>
  55. </nz-form-item>
  56. <nz-form-item>
  57. <nz-form-label [nzSpan]="7" nzRequired>Confirm Password</nz-form-label>
  58. <nz-form-control [nzSpan]="12" nzHasFeedback>
  59. <input nz-input type="password" formControlName="confirm" placeholder="confirm your password" />
  60. <nz-form-explain *ngIf="validateForm.get('confirm')?.dirty && validateForm.get('confirm')?.errors">
  61. <ng-container *ngIf="validateForm.get('confirm')?.hasError('required')">
  62. Please confirm your password!
  63. </ng-container>
  64. <ng-container *ngIf="validateForm.get('confirm')?.hasError('confirm')">
  65. Password is inconsistent!
  66. </ng-container>
  67. </nz-form-explain>
  68. </nz-form-control>
  69. </nz-form-item>
  70. <nz-form-item>
  71. <nz-form-label [nzSpan]="7" nzRequired>Comment</nz-form-label>
  72. <nz-form-control [nzSpan]="12">
  73. <textarea formControlName="comment" nz-input rows="2" placeholder="write any thing"></textarea>
  74. <nz-form-explain
  75. *ngIf="validateForm.get('comment')?.dirty && validateForm.get('comment')?.hasError('required')"
  76. >Please write something here!</nz-form-explain
  77. >
  78. </nz-form-control>
  79. </nz-form-item>
  80. <nz-form-item>
  81. <nz-form-control [nzOffset]="7" [nzSpan]="12">
  82. <button nz-button nzType="primary" [disabled]="!validateForm.valid">Submit</button>
  83. <button nz-button (click)="resetForm($event)">Reset</button>
  84. </nz-form-control>
  85. </nz-form-item>
  86. </form>
  87. `,
  88. styles: [
  89. `
  90. [nz-form] {
  91. max-width: 600px;
  92. }
  93. button {
  94. margin-left: 8px;
  95. }
  96. `
  97. ]
  98. })
  99. export class NzDemoFormValidateReactiveComponent {
  100. validateForm: FormGroup;
  101. submitForm = ($event: any, value: any) => {
  102. $event.preventDefault();
  103. for (const key in this.validateForm.controls) {
  104. this.validateForm.controls[key].markAsDirty();
  105. this.validateForm.controls[key].updateValueAndValidity();
  106. }
  107. console.log(value);
  108. };
  109. resetForm(e: MouseEvent): void {
  110. e.preventDefault();
  111. this.validateForm.reset();
  112. for (const key in this.validateForm.controls) {
  113. this.validateForm.controls[key].markAsPristine();
  114. this.validateForm.controls[key].updateValueAndValidity();
  115. }
  116. }
  117. validateConfirmPassword(): void {
  118. setTimeout(() => this.validateForm.controls.confirm.updateValueAndValidity());
  119. }
  120. userNameAsyncValidator = (control: FormControl) =>
  121. new Observable((observer: Observer<ValidationErrors | null>) => {
  122. setTimeout(() => {
  123. if (control.value === 'JasonWood') {
  124. observer.next({ error: true, duplicated: true });
  125. } else {
  126. observer.next(null);
  127. }
  128. observer.complete();
  129. }, 1000);
  130. });
  131. confirmValidator = (control: FormControl): { [s: string]: boolean } => {
  132. if (!control.value) {
  133. return { required: true };
  134. } else if (control.value !== this.validateForm.controls.password.value) {
  135. return { confirm: true, error: true };
  136. }
  137. return {};
  138. };
  139. constructor(private fb: FormBuilder) {
  140. this.validateForm = this.fb.group({
  141. userName: ['', [Validators.required], [this.userNameAsyncValidator]],
  142. email: ['', [Validators.email, Validators.required]],
  143. password: ['', [Validators.required]],
  144. confirm: ['', [this.confirmValidator]],
  145. comment: ['', [Validators.required]]
  146. });
  147. }
  148. }

Form表单 - 图8

模板驱动表单验证

我们在 nz-form-control 上 提供了 nzValidateStatusnzHasFeedback 等属性,当使用模板驱动表单时,可以自己定义校验的时机和内容。

  • nzValidateStatus: 校验状态,可选 'success', 'warning', 'error', 'validating'。
  • nzHasFeedback:用于给输入框添加反馈图标。
  • nz-form-explain:设置校验文案。
  1. import { Component } from '@angular/core';
  2. @Component({
  3. selector: 'nz-demo-form-validate-static',
  4. template: `
  5. <form nz-form>
  6. <nz-form-item>
  7. <nz-form-label [nzSpan]="5">Fail</nz-form-label>
  8. <nz-form-control nzValidateStatus="error" [nzSpan]="12">
  9. <input nz-input [ngModel]="'unavailable choice'" name="errorValid" />
  10. <nz-form-explain>Should be combination of numbers & alphabets</nz-form-explain>
  11. </nz-form-control>
  12. </nz-form-item>
  13. <nz-form-item>
  14. <nz-form-label [nzSpan]="5">Warning</nz-form-label>
  15. <nz-form-control nzValidateStatus="warning" [nzSpan]="12">
  16. <input nz-input [ngModel]="'Warning'" name="warningValid" />
  17. </nz-form-control>
  18. </nz-form-item>
  19. <nz-form-item>
  20. <nz-form-label [nzSpan]="5">Validating</nz-form-label>
  21. <nz-form-control [nzSpan]="12" nzValidateStatus="validating" nzHasFeedback>
  22. <input nz-input [ngModel]="'The content is being validated'" name="validating" />
  23. <nz-form-explain>I'm validating the content</nz-form-explain>
  24. </nz-form-control>
  25. </nz-form-item>
  26. <nz-form-item>
  27. <nz-form-label [nzSpan]="5">Success</nz-form-label>
  28. <nz-form-control [nzSpan]="12" nzValidateStatus="success" nzHasFeedback>
  29. <input nz-input [ngModel]="'The content'" name="successValid" />
  30. </nz-form-control>
  31. </nz-form-item>
  32. <nz-form-item>
  33. <nz-form-label [nzSpan]="5">Warning</nz-form-label>
  34. <nz-form-control [nzSpan]="12" nzValidateStatus="warning" nzHasFeedback>
  35. <input nz-input [ngModel]="'Warning'" name="warningHighValid" />
  36. <nz-form-explain>Should be combination of numbers & alphabets</nz-form-explain>
  37. </nz-form-control>
  38. </nz-form-item>
  39. <nz-form-item>
  40. <nz-form-label [nzSpan]="5">Fail</nz-form-label>
  41. <nz-form-control [nzSpan]="12" nzValidateStatus="error" nzHasFeedback>
  42. <input nz-input [ngModel]="'unavailable choice'" name="invalidValid" />
  43. <nz-form-explain>Should be combination of numbers & alphabets</nz-form-explain>
  44. </nz-form-control>
  45. </nz-form-item>
  46. <nz-form-item>
  47. <nz-form-label [nzSpan]="5">Success</nz-form-label>
  48. <nz-form-control [nzSpan]="12" nzValidateStatus="success" nzHasFeedback>
  49. <nz-date-picker name="date-picker-success" style="width: 100%"></nz-date-picker>
  50. </nz-form-control>
  51. </nz-form-item>
  52. <nz-form-item>
  53. <nz-form-label [nzSpan]="5">Warning</nz-form-label>
  54. <nz-form-control [nzSpan]="12" nzValidateStatus="warning" nzHasFeedback>
  55. <nz-time-picker name="time-picker-warning" style="width: 100%"></nz-time-picker>
  56. </nz-form-control>
  57. </nz-form-item>
  58. <nz-form-item>
  59. <nz-form-label [nzSpan]="5">Error</nz-form-label>
  60. <nz-form-control [nzSpan]="12" nzValidateStatus="error" nzHasFeedback>
  61. <nz-select name="select-error" [ngModel]="'Option 1'">
  62. <nz-option nzValue="Option 1" nzLabel="Option 1"></nz-option>
  63. <nz-option nzValue="Option 2" nzLabel="Option 2"></nz-option>
  64. </nz-select>
  65. </nz-form-control>
  66. </nz-form-item>
  67. <nz-form-item>
  68. <nz-form-label [nzSpan]="5">Validating</nz-form-label>
  69. <nz-form-control [nzSpan]="12" nzValidateStatus="validating" nzHasFeedback>
  70. <nz-select name="select-validate" [ngModel]="'Option 2'">
  71. <nz-option nzValue="Option 1" nzLabel="Option 1"></nz-option>
  72. <nz-option nzValue="Option 2" nzLabel="Option 2"></nz-option>
  73. </nz-select>
  74. </nz-form-control>
  75. </nz-form-item>
  76. <nz-form-item>
  77. <nz-form-label [nzSpan]="5">Success</nz-form-label>
  78. <nz-form-control [nzSpan]="12" nzValidateStatus="success" nzHasFeedback>
  79. <nz-input-number name="inputnumber-success" style="width:100%"></nz-input-number>
  80. </nz-form-control>
  81. </nz-form-item>
  82. </form>
  83. `,
  84. styles: [
  85. `
  86. [nz-form] {
  87. max-width: 600px;
  88. }
  89. nz-date-picker ::ng-deep .ant-calendar-picker {
  90. width: 100%;
  91. }
  92. `
  93. ]
  94. })
  95. export class NzDemoFormValidateStaticComponent {}

Form表单 - 图9

表单联动

使用 setValue 来动态设置其他控件的值。

  1. import { Component, OnInit } from '@angular/core';
  2. import { FormBuilder, FormGroup, Validators } from '@angular/forms';
  3. @Component({
  4. selector: 'nz-demo-form-coordinated',
  5. template: `
  6. <form nz-form [formGroup]="validateForm" (ngSubmit)="submitForm()">
  7. <nz-form-item>
  8. <nz-form-label [nzSpan]="5" nzRequired nzFor="note">Note</nz-form-label>
  9. <nz-form-control [nzSpan]="12">
  10. <input id="note" type="text" nz-input formControlName="note" />
  11. <nz-form-explain *ngIf="validateForm.get('note')?.dirty && validateForm.get('note')?.errors"
  12. >Please input your username!</nz-form-explain
  13. >
  14. </nz-form-control>
  15. </nz-form-item>
  16. <nz-form-item>
  17. <nz-form-label [nzSpan]="5" nzFor="gender" nzRequired>Gender</nz-form-label>
  18. <nz-form-control [nzSpan]="12">
  19. <nz-select
  20. id="gender"
  21. formControlName="gender"
  22. nzPlaceHolder="Select a option and change input text above"
  23. (ngModelChange)="genderChange($event)"
  24. >
  25. <nz-option nzValue="male" nzLabel="male"></nz-option>
  26. <nz-option nzValue="female" nzLabel="female"></nz-option>
  27. </nz-select>
  28. <nz-form-explain *ngIf="validateForm.get('gender')?.dirty && validateForm.get('gender')?.errors"
  29. >Please select your gender!</nz-form-explain
  30. >
  31. </nz-form-control>
  32. </nz-form-item>
  33. <nz-form-item>
  34. <nz-form-control [nzSpan]="12" [nzOffset]="5">
  35. <button nz-button nzType="primary">Submit</button>
  36. </nz-form-control>
  37. </nz-form-item>
  38. </form>
  39. `,
  40. styles: [
  41. `
  42. [nz-form] {
  43. max-width: 600px;
  44. }
  45. `
  46. ]
  47. })
  48. export class NzDemoFormCoordinatedComponent implements OnInit {
  49. validateForm: FormGroup;
  50. submitForm(): void {
  51. for (const i in this.validateForm.controls) {
  52. this.validateForm.controls[i].markAsDirty();
  53. this.validateForm.controls[i].updateValueAndValidity();
  54. }
  55. }
  56. genderChange(value: string): void {
  57. this.validateForm.get('note')!.setValue(value === 'male' ? 'Hi, man!' : 'Hi, lady!');
  58. }
  59. constructor(private fb: FormBuilder) {}
  60. ngOnInit(): void {
  61. this.validateForm = this.fb.group({
  62. note: [null, [Validators.required]],
  63. gender: [null, [Validators.required]]
  64. });
  65. }
  66. }

Form表单 - 图10

表单布局

表单有三种布局。

  1. import { Component, OnInit } from '@angular/core';
  2. import { FormBuilder, FormGroup, Validators } from '@angular/forms';
  3. @Component({
  4. selector: 'nz-demo-form-layout',
  5. template: `
  6. <form
  7. nz-form
  8. [nzLayout]="validateForm.get('formLayout')?.value"
  9. [formGroup]="validateForm"
  10. (ngSubmit)="submitForm()"
  11. >
  12. <nz-form-item>
  13. <nz-form-label [nzSpan]="isHorizontal ? 4 : null">Form Layout</nz-form-label>
  14. <nz-form-control [nzSpan]="isHorizontal ? 14 : null">
  15. <nz-radio-group formControlName="formLayout">
  16. <label nz-radio-button [nzValue]="'horizontal'">Horizontal</label>
  17. <label nz-radio-button [nzValue]="'vertical'">Vertical</label>
  18. <label nz-radio-button [nzValue]="'inline'">Inline</label>
  19. </nz-radio-group>
  20. </nz-form-control>
  21. </nz-form-item>
  22. <nz-form-item>
  23. <nz-form-label [nzSpan]="isHorizontal ? 4 : null">Field A</nz-form-label>
  24. <nz-form-control [nzSpan]="isHorizontal ? 14 : null">
  25. <input nz-input formControlName="fieldA" placeholder="input placeholder" />
  26. <nz-form-explain *ngIf="validateForm.get('fieldA')?.dirty && validateForm.get('fieldA')?.errors"
  27. >Please input your username!</nz-form-explain
  28. >
  29. </nz-form-control>
  30. </nz-form-item>
  31. <nz-form-item>
  32. <nz-form-label [nzSpan]="isHorizontal ? 4 : null">Field B</nz-form-label>
  33. <nz-form-control [nzSpan]="isHorizontal ? 14 : null">
  34. <input nz-input formControlName="filedB" placeholder="input placeholder" />
  35. <nz-form-explain *ngIf="validateForm.get('filedB')?.dirty && validateForm.get('filedB')?.errors"
  36. >Please input your Password!</nz-form-explain
  37. >
  38. </nz-form-control>
  39. </nz-form-item>
  40. <nz-form-item>
  41. <nz-form-control [nzSpan]="isHorizontal ? 14 : null" [nzOffset]="isHorizontal ? 4 : null">
  42. <button nz-button nzType="primary">Submit</button>
  43. </nz-form-control>
  44. </nz-form-item>
  45. </form>
  46. `,
  47. styles: [
  48. `
  49. [nz-form]:not(.ant-form-inline):not(.ant-form-vertical) {
  50. max-width: 600px;
  51. }
  52. `
  53. ]
  54. })
  55. export class NzDemoFormLayoutComponent implements OnInit {
  56. validateForm: FormGroup;
  57. submitForm(): void {
  58. for (const i in this.validateForm.controls) {
  59. this.validateForm.controls[i].markAsDirty();
  60. this.validateForm.controls[i].updateValueAndValidity();
  61. }
  62. }
  63. get isHorizontal(): boolean {
  64. return this.validateForm.controls.formLayout && this.validateForm.controls.formLayout.value === 'horizontal';
  65. }
  66. constructor(private fb: FormBuilder) {}
  67. ngOnInit(): void {
  68. this.validateForm = this.fb.group({
  69. formLayout: ['horizontal'],
  70. fieldA: [null, [Validators.required]],
  71. filedB: [null, [Validators.required]]
  72. });
  73. }
  74. }

Form表单 - 图11

动态校验规则

根据不同情况执行不同的校验规则。

  1. import { Component, OnInit } from '@angular/core';
  2. import { FormBuilder, FormGroup, Validators } from '@angular/forms';
  3. @Component({
  4. selector: 'nz-demo-form-dynamic-rule',
  5. template: `
  6. <form nz-form [formGroup]="validateForm" (ngSubmit)="submitForm()">
  7. <nz-form-item>
  8. <nz-form-label [nzSpan]="4" nzRequired nzFor="name">Name</nz-form-label>
  9. <nz-form-control [nzSpan]="8">
  10. <input type="text" nz-input formControlName="name" placeholder="Please input your name" />
  11. <nz-form-explain *ngIf="validateForm.get('name')?.dirty && validateForm.get('name')?.errors"
  12. >Please input your name</nz-form-explain
  13. >
  14. </nz-form-control>
  15. </nz-form-item>
  16. <nz-form-item>
  17. <nz-form-label [nzSpan]="4" nzFor="nickname" [nzRequired]="validateForm.get('required')?.value"
  18. >Nickname</nz-form-label
  19. >
  20. <nz-form-control [nzSpan]="8">
  21. <input type="text" nz-input formControlName="nickname" placeholder="Please input your nickname" />
  22. <nz-form-explain *ngIf="validateForm.get('nickname')?.dirty && validateForm.get('nickname')?.errors"
  23. >Please input your nickname</nz-form-explain
  24. >
  25. </nz-form-control>
  26. </nz-form-item>
  27. <nz-form-item>
  28. <nz-form-control [nzSpan]="8" [nzOffset]="4">
  29. <label nz-checkbox formControlName="required" (ngModelChange)="requiredChange($event)"
  30. >Nickname is required</label
  31. >
  32. </nz-form-control>
  33. </nz-form-item>
  34. <nz-form-item>
  35. <nz-form-control [nzSpan]="8" [nzOffset]="4">
  36. <button nz-button nzType="primary">Check</button>
  37. </nz-form-control>
  38. </nz-form-item>
  39. </form>
  40. `
  41. })
  42. export class NzDemoFormDynamicRuleComponent implements OnInit {
  43. validateForm: FormGroup;
  44. submitForm(): void {
  45. for (const i in this.validateForm.controls) {
  46. this.validateForm.controls[i].markAsDirty();
  47. this.validateForm.controls[i].updateValueAndValidity();
  48. }
  49. }
  50. requiredChange(required: boolean): void {
  51. if (!required) {
  52. this.validateForm.get('nickname')!.clearValidators();
  53. this.validateForm.get('nickname')!.markAsPristine();
  54. } else {
  55. this.validateForm.get('nickname')!.setValidators(Validators.required);
  56. this.validateForm.get('nickname')!.markAsDirty();
  57. }
  58. this.validateForm.get('nickname')!.updateValueAndValidity();
  59. }
  60. constructor(private fb: FormBuilder) {}
  61. ngOnInit(): void {
  62. this.validateForm = this.fb.group({
  63. name: [null, [Validators.required]],
  64. nickname: [null],
  65. required: [false]
  66. });
  67. }
  68. }

API

单独引入此组件

想要了解更多关于单独引入组件的内容,可以在快速上手页面进行查看。

  1. import { NzFormModule } from 'ng-zorro-antd';

nz-formcomponent

参数说明类型默认值
[nzLayout]表单布局'horizontal'|'vertical'|'inline''horizontal'
[nzNoColon]配置 nz-form-label[nzNoColon] 的默认值booleanfalse

nz-form-itemcomponent

表单项用于区分表单中不同的区域,包含表单域和表单标签(可选)。

所有 nz-row 的参数在 nz-form-item 上均可直接使用。

参数说明类型默认值
[nzFlex]是否Flex布局booleanfalse

nz-form-labelcomponent

用于标示当前表单项的内容,可选。

所有 nz-col 的参数在 nz-form-label 上均可直接使用。

参数说明类型默认值
[nzRequired]当前项是否为必填,仅影响样式booleanfalse
[nzNoColon]是否不显示 label 后面的冒号booleanfalse
[nzFor]label 标签的 for 属性string-
[nzColon]配合 label 属性使用,表示是否显示 label 后面的冒号booleantrue

nz-form-controlcomponent

注意:由于 Angular Form 目前提供的状态变更订阅不完整。手动更改表单状态时,例如 markAsDirty 后,需要执行 updateValueAndValidity 通知 nz-form-control 进行状态变更。

表单一定会包含表单域,表单域可以是输入控件,标准表单域,标签,下拉菜单,文本域等。

所有 nz-col 的参数在 nz-form-control 上均可直接使用。

参数说明类型默认值
[nzValidateStatus]Reactive Forms:会根据 FormControl 的状态自动生成校验状态FormControlnz-form-control 中包裹的第一个 FormControl
[nzValidateStatus]Template-driven Forms:校验状态'success'|'warning'|'error'|'validating'-
[nzHasFeedback]配合 nzValidateStatus 属性使用,展示校验状态图标booleanfalse

从 7.3.0 版本开始,nz-form-control 提供了 status 变量用于指示校验状态,status 会自动根据 [nzValidateStatus]'success'|'warning'|'error'|'validating' 中自动切换,用户可以通过模板变量导出 status 用于切换提示信息。

nz-form-explaincomponent

用于显示提示信息,会自动根据当前的 nzValidateStatus 显示不同的颜色

注意:每个 nz-form-item 下最多只能有一个 nz-form-explain

nz-form-extracomponent

用于显示表单额外提示信息

nz-form-splitcomponent

用于显示分隔符 -

nz-form-textcomponent

nz-form-control 中直接显示文本