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>
  1. import { NzFormModule } from 'ng-zorro-antd/form';

代码演示Form表单 - 图2

Form表单 - 图3

内联登录栏

内联登录栏,常用在顶部导航栏中。

  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 nzErrorTip="Please input your username!">
  9. <nz-input-group nzPrefixIcon="user">
  10. <input formControlName="userName" nz-input placeholder="Username" />
  11. </nz-input-group>
  12. </nz-form-control>
  13. </nz-form-item>
  14. <nz-form-item>
  15. <nz-form-control nzErrorTip="Please input your Password!">
  16. <nz-input-group nzPrefixIcon="lock">
  17. <input formControlName="password" nz-input type="password" placeholder="Password" />
  18. </nz-input-group>
  19. </nz-form-control>
  20. </nz-form-item>
  21. <nz-form-item>
  22. <nz-form-control>
  23. <button nz-button nzType="primary" [disabled]="!validateForm.valid">Log in</button>
  24. </nz-form-control>
  25. </nz-form-item>
  26. </form>
  27. `
  28. })
  29. export class NzDemoFormHorizontalLoginComponent implements OnInit {
  30. validateForm!: FormGroup;
  31. submitForm(): void {
  32. for (const i in this.validateForm.controls) {
  33. this.validateForm.controls[i].markAsDirty();
  34. this.validateForm.controls[i].updateValueAndValidity();
  35. }
  36. }
  37. constructor(private fb: FormBuilder) {}
  38. ngOnInit(): void {
  39. this.validateForm = this.fb.group({
  40. userName: [null, [Validators.required]],
  41. password: [null, [Validators.required]],
  42. remember: [true]
  43. });
  44. }
  45. }

Form表单 - 图4

登录框

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

  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 nzErrorTip="Please input your username!">
  9. <nz-input-group nzPrefixIcon="user">
  10. <input type="text" nz-input formControlName="userName" placeholder="Username" />
  11. </nz-input-group>
  12. </nz-form-control>
  13. </nz-form-item>
  14. <nz-form-item>
  15. <nz-form-control nzErrorTip="Please input your Password!">
  16. <nz-input-group nzPrefixIcon="lock">
  17. <input type="password" nz-input formControlName="password" placeholder="Password" />
  18. </nz-input-group>
  19. </nz-form-control>
  20. </nz-form-item>
  21. <div nz-row class="login-form-margin">
  22. <div nz-col [nzSpan]="12">
  23. <label nz-checkbox formControlName="remember">
  24. <span>Remember me</span>
  25. </label>
  26. </div>
  27. <div nz-col [nzSpan]="12">
  28. <a class="login-form-forgot">Forgot password</a>
  29. </div>
  30. </div>
  31. <button nz-button class="login-form-button login-form-margin" [nzType]="'primary'">Log in</button>
  32. Or <a> register now! </a>
  33. </form>
  34. `,
  35. styles: [
  36. `
  37. .login-form {
  38. max-width: 300px;
  39. }
  40. .login-form-margin {
  41. margin-bottom: 16px;
  42. }
  43. .login-form-forgot {
  44. float: right;
  45. }
  46. .login-form-button {
  47. width: 100%;
  48. }
  49. `
  50. ]
  51. })
  52. export class NzDemoFormNormalLoginComponent implements OnInit {
  53. validateForm!: FormGroup;
  54. submitForm(): void {
  55. for (const i in this.validateForm.controls) {
  56. this.validateForm.controls[i].markAsDirty();
  57. this.validateForm.controls[i].updateValueAndValidity();
  58. }
  59. }
  60. constructor(private fb: FormBuilder) {}
  61. ngOnInit(): void {
  62. this.validateForm = this.fb.group({
  63. userName: [null, [Validators.required]],
  64. password: [null, [Validators.required]],
  65. remember: [true]
  66. });
  67. }
  68. }

Form表单 - 图5

注册新用户

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

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

Form表单 - 图6

高级搜索

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

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

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

Form表单 - 图7

动态增减表单项

动态增加、减少表单项。

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

Form表单 - 图8

时间类控件

时间类组件的输入和输出类型均为 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-date-picker nzMode="month" formControlName="monthPicker"></nz-date-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表单 - 图9

响应式表单验证

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

  1. nzValidateStatus: 校验状态,默认自动从 nz-form-control 中的 NgControl 获得校验状态,也可以手动指定为特定的 NgControl
  2. nzHasFeedback:用于给输入框添加反馈图标。
  3. nzSuccessTip``nzWarningTip``nzErrorTip``nzValidatingTip:设置不同状态校验文案。

    当同一种状态下存在多种提示情况时,nzSuccessTip``nzWarningTip``nzErrorTip``nzValidatingTip 均支持传入 TemplateRef<{ $implicit: FormControl } 类型,可以通过模板变量)导出 FormControl 后用于切换不同的提示信息。
    当 FormControl.status 为 INVALID 并且错误包含 {warning:true} 时,nz-form-control 显示警告状态。

  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(validateForm.value)">
  8. <nz-form-item>
  9. <nz-form-label [nzSpan]="7" nzRequired>Username</nz-form-label>
  10. <nz-form-control [nzSpan]="12" nzHasFeedback nzValidatingTip="Validating..." [nzErrorTip]="userErrorTpl">
  11. <input nz-input formControlName="userName" placeholder="async validate try to write JasonWood" />
  12. <ng-template #userErrorTpl let-control>
  13. <ng-container *ngIf="control.hasError('required')">
  14. Please input your username!
  15. </ng-container>
  16. <ng-container *ngIf="control.hasError('duplicated')">
  17. The username is redundant!
  18. </ng-container>
  19. </ng-template>
  20. </nz-form-control>
  21. </nz-form-item>
  22. <nz-form-item>
  23. <nz-form-label [nzSpan]="7" nzRequired>E-mail</nz-form-label>
  24. <nz-form-control [nzSpan]="12" nzHasFeedback [nzErrorTip]="emailErrorTpl">
  25. <input nz-input formControlName="email" placeholder="email" type="email" />
  26. <ng-template #emailErrorTpl let-control>
  27. <ng-container *ngIf="control.hasError('email')">
  28. The input is not valid E-mail!
  29. </ng-container>
  30. <ng-container *ngIf="control.hasError('required')">
  31. Please input your E-mail!
  32. </ng-container>
  33. </ng-template>
  34. </nz-form-control>
  35. </nz-form-item>
  36. <nz-form-item>
  37. <nz-form-label [nzSpan]="7" nzRequired>Password</nz-form-label>
  38. <nz-form-control [nzSpan]="12" nzHasFeedback nzErrorTip="Please input your password!">
  39. <input nz-input type="password" formControlName="password" (ngModelChange)="validateConfirmPassword()" />
  40. </nz-form-control>
  41. </nz-form-item>
  42. <nz-form-item>
  43. <nz-form-label [nzSpan]="7" nzRequired>Confirm Password</nz-form-label>
  44. <nz-form-control [nzSpan]="12" nzHasFeedback [nzErrorTip]="passwordErrorTpl">
  45. <input nz-input type="password" formControlName="confirm" placeholder="confirm your password" />
  46. <ng-template #passwordErrorTpl let-control>
  47. <ng-container *ngIf="control.hasError('required')">
  48. Please confirm your password!
  49. </ng-container>
  50. <ng-container *ngIf="control.hasError('confirm')">
  51. Password is inconsistent!
  52. </ng-container>
  53. </ng-template>
  54. </nz-form-control>
  55. </nz-form-item>
  56. <nz-form-item>
  57. <nz-form-label [nzSpan]="7" nzRequired>Comment</nz-form-label>
  58. <nz-form-control [nzSpan]="12" nzErrorTip="Please write something here!">
  59. <textarea formControlName="comment" nz-input rows="2" placeholder="write any thing"></textarea>
  60. </nz-form-control>
  61. </nz-form-item>
  62. <nz-form-item>
  63. <nz-form-control [nzOffset]="7" [nzSpan]="12">
  64. <button nz-button nzType="primary" [disabled]="!validateForm.valid">Submit</button>
  65. <button nz-button (click)="resetForm($event)">Reset</button>
  66. </nz-form-control>
  67. </nz-form-item>
  68. </form>
  69. `,
  70. styles: [
  71. `
  72. [nz-form] {
  73. max-width: 600px;
  74. }
  75. button {
  76. margin-left: 8px;
  77. }
  78. `
  79. ]
  80. })
  81. export class NzDemoFormValidateReactiveComponent {
  82. validateForm: FormGroup;
  83. submitForm(value: { userName: string; email: string; password: string; confirm: string; comment: string }): void {
  84. for (const key in this.validateForm.controls) {
  85. this.validateForm.controls[key].markAsDirty();
  86. this.validateForm.controls[key].updateValueAndValidity();
  87. }
  88. console.log(value);
  89. }
  90. resetForm(e: MouseEvent): void {
  91. e.preventDefault();
  92. this.validateForm.reset();
  93. for (const key in this.validateForm.controls) {
  94. this.validateForm.controls[key].markAsPristine();
  95. this.validateForm.controls[key].updateValueAndValidity();
  96. }
  97. }
  98. validateConfirmPassword(): void {
  99. setTimeout(() => this.validateForm.controls.confirm.updateValueAndValidity());
  100. }
  101. userNameAsyncValidator = (control: FormControl) =>
  102. new Observable((observer: Observer<ValidationErrors | null>) => {
  103. setTimeout(() => {
  104. if (control.value === 'JasonWood') {
  105. // you have to return `{error: true}` to mark it as an error event
  106. observer.next({ error: true, duplicated: true });
  107. } else {
  108. observer.next(null);
  109. }
  110. observer.complete();
  111. }, 1000);
  112. });
  113. confirmValidator = (control: FormControl): { [s: string]: boolean } => {
  114. if (!control.value) {
  115. return { error: true, required: true };
  116. } else if (control.value !== this.validateForm.controls.password.value) {
  117. return { confirm: true, error: true };
  118. }
  119. return {};
  120. };
  121. constructor(private fb: FormBuilder) {
  122. this.validateForm = this.fb.group({
  123. userName: ['', [Validators.required], [this.userNameAsyncValidator]],
  124. email: ['', [Validators.email, Validators.required]],
  125. password: ['', [Validators.required]],
  126. confirm: ['', [this.confirmValidator]],
  127. comment: ['', [Validators.required]]
  128. });
  129. }
  130. }

Form表单 - 图10

模板驱动表单验证

当使用模板驱动表单时,模板可以根据模板设定自动进行校验。

  1. nzHasFeedback:用于给输入框添加反馈图标。
  2. nzSuccessTip``nzWarningTip``nzErrorTip``nzValidatingTip:设置不同状态校验文案。

    当同一种状态下存在多种提示情况时,nzSuccessTip``nzWarningTip``nzErrorTip``nzValidatingTip 均支持传入 TemplateRef<{ $implicit: NgModel } 类型,可以通过模板变量)导出 NgModel 后用于切换不同的提示信息。

  1. import { Component } from '@angular/core';
  2. @Component({
  3. selector: 'nz-demo-form-validate-template',
  4. template: `
  5. <form nz-form>
  6. <nz-form-item>
  7. <nz-form-label [nzSpan]="5">Required</nz-form-label>
  8. <nz-form-control nzHasFeedback [nzSpan]="12" nzErrorTip="Input is required">
  9. <input nz-input [ngModel]="'Required Input'" name="required" required />
  10. </nz-form-control>
  11. </nz-form-item>
  12. <nz-form-item>
  13. <nz-form-label [nzSpan]="5">MaxLength</nz-form-label>
  14. <nz-form-control nzHasFeedback [nzSpan]="12" nzErrorTip="MaxLength is 6">
  15. <input nz-input [ngModel]="'MaxLength is 6'" name="maxlength" maxlength="6" />
  16. </nz-form-control>
  17. </nz-form-item>
  18. <nz-form-item>
  19. <nz-form-label [nzSpan]="5">MinLength</nz-form-label>
  20. <nz-form-control nzHasFeedback [nzSpan]="12" nzErrorTip="MinLength is 6">
  21. <input nz-input [ngModel]="'MinLength is 6'" name="minlength" minlength="6" />
  22. </nz-form-control>
  23. </nz-form-item>
  24. <nz-form-item>
  25. <nz-form-label [nzSpan]="5">Email</nz-form-label>
  26. <nz-form-control nzHasFeedback [nzSpan]="12" nzErrorTip="Email is not valid">
  27. <input nz-input [ngModel]="'Input Email'" name="email" email />
  28. </nz-form-control>
  29. </nz-form-item>
  30. <nz-form-item>
  31. <nz-form-label [nzSpan]="5">Pattern</nz-form-label>
  32. <nz-form-control nzHasFeedback [nzSpan]="12" nzErrorTip="Pattern not match">
  33. <input nz-input [ngModel]="'Match pattern'" name="pattern" pattern=".{3,}" />
  34. </nz-form-control>
  35. </nz-form-item>
  36. <nz-form-item>
  37. <nz-form-label [nzSpan]="5">Mix</nz-form-label>
  38. <nz-form-control nzHasFeedback [nzSpan]="12" [nzErrorTip]="combineTpl">
  39. <input nz-input [ngModel]="'MaxLength is 12 and MinLength is 6'" name="mix" minlength="6" maxlength="12" required />
  40. <ng-template #combineTpl let-control>
  41. <ng-container *ngIf="control.hasError('maxlength')">MaxLength is 12</ng-container>
  42. <ng-container *ngIf="control.hasError('minlength')">MinLength is 6</ng-container>
  43. <ng-container *ngIf="control.hasError('required')">Input is required</ng-container>
  44. </ng-template>
  45. </nz-form-control>
  46. </nz-form-item>
  47. </form>
  48. `,
  49. styles: [
  50. `
  51. [nz-form] {
  52. max-width: 600px;
  53. }
  54. `
  55. ]
  56. })
  57. export class NzDemoFormValidateTemplateComponent {}

Form表单 - 图11

自动提示

让提示变得更简单。
需要预先自定义 Validators 和提供 nzAutoTips,它们优先级如下:

  • Validators > nzAutoTips
  • 通过 @Input 设置 nzAutoTips
  • 通过全局配置设置 nzAutoTips

另外,你可以使用 nzDisableAutoTips 去禁用它。

  1. import { Component } from '@angular/core';
  2. import { AbstractControl, FormBuilder, FormControl, FormGroup, ValidatorFn, Validators } from '@angular/forms';
  3. import { NzSafeAny } from 'ng-zorro-antd/core/types';
  4. import { Observable, Observer } from 'rxjs';
  5. @Component({
  6. selector: 'nz-demo-form-auto-tips',
  7. template: `
  8. <form nz-form [nzAutoTips]="autoTips" [formGroup]="validateForm" (ngSubmit)="submitForm(validateForm.value)">
  9. <nz-form-item>
  10. <nz-form-label [nzSpan]="7" nzRequired>Username</nz-form-label>
  11. <nz-form-control [nzSpan]="12" nzValidatingTip="Validating...">
  12. <input nz-input formControlName="userName" placeholder="async validate try to write JasonWood" />
  13. </nz-form-control>
  14. </nz-form-item>
  15. <nz-form-item>
  16. <nz-form-label [nzSpan]="7" nzRequired>Mobile</nz-form-label>
  17. <nz-form-control [nzSpan]="12">
  18. <input nz-input formControlName="mobile" placeholder="mobile" />
  19. </nz-form-control>
  20. </nz-form-item>
  21. <nz-form-item>
  22. <nz-form-label [nzSpan]="7" nzRequired>E-mail</nz-form-label>
  23. <nz-form-control [nzSpan]="12">
  24. <input nz-input formControlName="email" placeholder="email" type="email" />
  25. </nz-form-control>
  26. </nz-form-item>
  27. <nz-form-item>
  28. <nz-form-label [nzSpan]="7" nzRequired>Password</nz-form-label>
  29. <nz-form-control [nzSpan]="12" nzDisableAutoTips nzErrorTip="Please input your password!">
  30. <input nz-input type="password" formControlName="password" (ngModelChange)="validateConfirmPassword()" />
  31. </nz-form-control>
  32. </nz-form-item>
  33. <nz-form-item>
  34. <nz-form-label [nzSpan]="7" nzRequired>Confirm Password</nz-form-label>
  35. <nz-form-control [nzSpan]="12" nzDisableAutoTips [nzErrorTip]="passwordErrorTpl">
  36. <input nz-input type="password" formControlName="confirm" placeholder="confirm your password" />
  37. <ng-template #passwordErrorTpl let-control>
  38. <ng-container *ngIf="control.hasError('required')">
  39. Please confirm your password!
  40. </ng-container>
  41. <ng-container *ngIf="control.hasError('confirm')">
  42. Password is inconsistent!
  43. </ng-container>
  44. </ng-template>
  45. </nz-form-control>
  46. </nz-form-item>
  47. <nz-form-item>
  48. <nz-form-control [nzOffset]="7" [nzSpan]="12">
  49. <button nz-button nzType="primary">Submit</button>
  50. </nz-form-control>
  51. </nz-form-item>
  52. </form>
  53. `,
  54. styles: [
  55. `
  56. [nz-form] {
  57. max-width: 600px;
  58. }
  59. `
  60. ]
  61. })
  62. export class NzDemoFormAutoTipsComponent {
  63. validateForm: FormGroup;
  64. // current locale is key of the nzAutoTips
  65. autoTips: Record<string, Record<string, string>> = {
  66. 'zh-cn': {
  67. required: '必填项',
  68. email: '邮箱格式不正确'
  69. },
  70. en: {
  71. required: 'Input is required',
  72. email: 'The input is not valid email'
  73. }
  74. };
  75. submitForm(value: { userName: string; email: string; password: string; confirm: string; comment: string }): void {
  76. for (const key in this.validateForm.controls) {
  77. this.validateForm.controls[key].markAsDirty();
  78. this.validateForm.controls[key].updateValueAndValidity();
  79. }
  80. console.log(value);
  81. }
  82. validateConfirmPassword(): void {
  83. setTimeout(() => this.validateForm.controls.confirm.updateValueAndValidity());
  84. }
  85. userNameAsyncValidator = (control: FormControl) =>
  86. new Observable((observer: Observer<MyValidationErrors | null>) => {
  87. setTimeout(() => {
  88. if (control.value === 'JasonWood') {
  89. observer.next({
  90. duplicated: { 'zh-cn': `用户名已存在`, en: `The username is redundant!` }
  91. });
  92. } else {
  93. observer.next(null);
  94. }
  95. observer.complete();
  96. }, 1000);
  97. });
  98. confirmValidator = (control: FormControl): { [s: string]: boolean } => {
  99. if (!control.value) {
  100. return { error: true, required: true };
  101. } else if (control.value !== this.validateForm.controls.password.value) {
  102. return { confirm: true, error: true };
  103. }
  104. return {};
  105. };
  106. constructor(private fb: FormBuilder) {
  107. // use `MyValidators`
  108. const { required, maxLength, minLength, email, mobile } = MyValidators;
  109. this.validateForm = this.fb.group({
  110. userName: ['', [required, maxLength(12), minLength(6)], [this.userNameAsyncValidator]],
  111. mobile: ['', [required, mobile]],
  112. email: ['', [required, email]],
  113. password: ['', [required]],
  114. confirm: ['', [this.confirmValidator]]
  115. });
  116. }
  117. }
  118. // current locale is key of the MyErrorsOptions
  119. export type MyErrorsOptions = { 'zh-cn': string; en: string } & Record<string, NzSafeAny>;
  120. export type MyValidationErrors = Record<string, MyErrorsOptions>;
  121. export class MyValidators extends Validators {
  122. static minLength(minLength: number): ValidatorFn {
  123. return (control: AbstractControl): MyValidationErrors | null => {
  124. if (Validators.minLength(minLength)(control) === null) {
  125. return null;
  126. }
  127. return { minlength: { 'zh-cn': `最小长度为 ${minLength}`, en: `MinLength is ${minLength}` } };
  128. };
  129. }
  130. static maxLength(maxLength: number): ValidatorFn {
  131. return (control: AbstractControl): MyValidationErrors | null => {
  132. if (Validators.maxLength(maxLength)(control) === null) {
  133. return null;
  134. }
  135. return { maxlength: { 'zh-cn': `最大长度为 ${maxLength}`, en: `MaxLength is ${maxLength}` } };
  136. };
  137. }
  138. static mobile(control: AbstractControl): MyValidationErrors | null {
  139. const value = control.value;
  140. if (isEmptyInputValue(value)) {
  141. return null;
  142. }
  143. return isMobile(value) ? null : { mobile: { 'zh-cn': `手机号码格式不正确`, en: `Mobile phone number is not valid` } };
  144. }
  145. }
  146. function isEmptyInputValue(value: NzSafeAny): boolean {
  147. return value == null || value.length === 0;
  148. }
  149. function isMobile(value: string): boolean {
  150. return typeof value === 'string' && /(^1\d{10}$)/.test(value);
  151. }

Form表单 - 图12

手动指定表单状态

用户可以在通过 nz-form-controlnzValidateStatus 属性直接设定表单的状态。

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

Form表单 - 图13

表单联动

使用 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" nzErrorTip="Please input your username!">
  10. <input id="note" type="text" nz-input formControlName="note" />
  11. </nz-form-control>
  12. </nz-form-item>
  13. <nz-form-item>
  14. <nz-form-label [nzSpan]="5" nzFor="gender" nzRequired>Gender</nz-form-label>
  15. <nz-form-control [nzSpan]="12" nzErrorTip="Please select your gender!">
  16. <nz-select
  17. id="gender"
  18. formControlName="gender"
  19. nzPlaceHolder="Select a option and change input text above"
  20. (ngModelChange)="genderChange($event)"
  21. >
  22. <nz-option nzValue="male" nzLabel="male"></nz-option>
  23. <nz-option nzValue="female" nzLabel="female"></nz-option>
  24. </nz-select>
  25. </nz-form-control>
  26. </nz-form-item>
  27. <nz-form-item>
  28. <nz-form-control [nzSpan]="12" [nzOffset]="5">
  29. <button nz-button nzType="primary">Submit</button>
  30. </nz-form-control>
  31. </nz-form-item>
  32. </form>
  33. `,
  34. styles: [
  35. `
  36. [nz-form] {
  37. max-width: 600px;
  38. }
  39. `
  40. ]
  41. })
  42. export class NzDemoFormCoordinatedComponent 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. genderChange(value: string): void {
  51. this.validateForm.get('note')!.setValue(value === 'male' ? 'Hi, man!' : 'Hi, lady!');
  52. }
  53. constructor(private fb: FormBuilder) {}
  54. ngOnInit(): void {
  55. this.validateForm = this.fb.group({
  56. note: [null, [Validators.required]],
  57. gender: [null, [Validators.required]]
  58. });
  59. }
  60. }

Form表单 - 图14

表单布局

表单有三种布局。

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

Form表单 - 图15

动态校验规则

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

  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" nzErrorTip="Please input your name">
  10. <input type="text" nz-input formControlName="name" placeholder="Please input your name" />
  11. </nz-form-control>
  12. </nz-form-item>
  13. <nz-form-item>
  14. <nz-form-label [nzSpan]="4" nzFor="nickname" [nzRequired]="validateForm.get('required')?.value">Nickname</nz-form-label>
  15. <nz-form-control [nzSpan]="8" nzErrorTip="Please input your nickname">
  16. <input type="text" nz-input formControlName="nickname" placeholder="Please input your nickname" />
  17. </nz-form-control>
  18. </nz-form-item>
  19. <nz-form-item>
  20. <nz-form-control [nzSpan]="8" [nzOffset]="4">
  21. <label nz-checkbox formControlName="required" (ngModelChange)="requiredChange($event)">Nickname is required</label>
  22. </nz-form-control>
  23. </nz-form-item>
  24. <nz-form-item>
  25. <nz-form-control [nzSpan]="8" [nzOffset]="4">
  26. <button nz-button nzType="primary">Check</button>
  27. </nz-form-control>
  28. </nz-form-item>
  29. </form>
  30. `
  31. })
  32. export class NzDemoFormDynamicRuleComponent implements OnInit {
  33. validateForm!: FormGroup;
  34. submitForm(): void {
  35. for (const i in this.validateForm.controls) {
  36. this.validateForm.controls[i].markAsDirty();
  37. this.validateForm.controls[i].updateValueAndValidity();
  38. }
  39. }
  40. requiredChange(required: boolean): void {
  41. if (!required) {
  42. this.validateForm.get('nickname')!.clearValidators();
  43. this.validateForm.get('nickname')!.markAsPristine();
  44. } else {
  45. this.validateForm.get('nickname')!.setValidators(Validators.required);
  46. this.validateForm.get('nickname')!.markAsDirty();
  47. }
  48. this.validateForm.get('nickname')!.updateValueAndValidity();
  49. }
  50. constructor(private fb: FormBuilder) {}
  51. ngOnInit(): void {
  52. this.validateForm = this.fb.group({
  53. name: [null, [Validators.required]],
  54. nickname: [null],
  55. required: [false]
  56. });
  57. }
  58. }

API

[nz-form]directive

参数说明类型默认值全局配置
[nzLayout]表单布局‘horizontal’ | ‘vertical’ | ‘inline’‘horizontal’
[nzNoColon]配置 nz-form-label[nzNoColon] 的默认值booleanfalse
[nzAutoTips]配置 nz-form-control[nzAutoTips] 的默认值, 具体用法请参考示例:自动提示Record<string, Record<string, string>>{}
[nzDisableAutoTips]配置 nz-form-control[nzDisableAutoTips] 的默认值booleanfalse

nz-form-itemcomponent

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

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

nz-form-labelcomponent

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

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

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

nz-form-controlcomponent

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

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

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

参数说明类型默认值
[nzValidateStatus]会根据传入的 FormControlNgModel 自动生成校验状态,也可以直接指定状态,不传入时默认值为 nz-form-control 中包裹的第一个 FormControlNgModel‘success’ | ‘warning’ | ‘error’ | ‘validating’ | FormControl | NgModelnz-form-control 中包裹的第一个 FormControlNgModel
[nzHasFeedback]配合 nzValidateStatus 属性使用,展示校验状态图标booleanfalse
[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 }>-
[nzAutoTips]配置提示的对象, 具体用法请参考示例:自动提示Record<string, Record<string, string>>--
[nzDisableAutoTips]禁用自动提示boolean--

nz-form-splitcomponent

用于显示分隔符 -

nz-form-textcomponent

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