如何取消Angular订单表单按回车键触发验证的行为
如何阻止Angular表单按下回车键自动触发表单验证
问题描述
我在Angular应用中创建了一个客户订单表单,希望仅在用户点击发送订单按钮时才触发表单验证。目前点击按钮验证正常,但用户按下回车键时会自动触发验证,需要避免该行为。
现有HTML代码
<form [formGroup]="orderForm"> <div class="container form-container"> <h4 class="container__title">{{ 'order.form.message.printout' | translate }}</h4> <!--Type de produit--> <div formArrayName="orders" ngDefaultControl> <div *ngFor="let order of ordersFormArray.controls; let i = index"> <div [formGroupName]="i"> <mat-form-field appearance="fill" class="A-form-field"> <mat-label>{{ 'order.form.field.product' | translate }}</mat-label> <mat-select formControlName="produit" (selectionChange)="productChangeAction($event.value, i)" > <mat-option id="{{ 'label-option' + i }}" *ngFor="let product of productList" [value]="product.label" > {{ product.label }} </mat-option> </mat-select> </mat-form-field> <!--Documents associés au produit--> <mat-form-field appearance="fill" class="A-form-field"> <mat-label>{{ 'order.form.field.documents' | translate }}</mat-label> <mat-select formControlName="document" > <mat-option *ngFor="let document of documents[i]" [value]="document.label" > {{ document.label }} </mat-option> </mat-select> </mat-form-field> <!--Quantité document commandé--> <mat-form-field appearance="fill" class="A-form-field"> <mat-label>{{ 'order.form.field.maxQuantity' | translate }}</mat-label> <input matInput type="number" formControlName="quantite"/> </mat-form-field> <mat-icon (click)="removeOrder(i)">delete_outline</mat-icon> <mat-error *ngIf="ordersFormArray.controls[i]?.hasError('validateQuantity')"> {{ 'order.form.message.documentsAuthorizedQuantityError' | translate: { maxQuantity: ordersFormArray.controls[i].getError('validateQuantity').max, documentLabel: ordersFormArray.controls[i].getError('validateQuantity').documentLabel } }} </mat-error> </div> </div> </div> <button mat-raised-button type="button" color="primary" data-test="add-order-button" (click)="addOrder()" class="add-order-button"> <mat-icon>add</mat-icon> {{ 'order.form.button.addOrder' | translate }} </button> </div> <div class="container"> <h4 class="container__title">{{ 'order.form.message.leaveComment' | translate }}</h4> <mat-form-field class="B-form-field" > <mat-label>{{ 'order.form.message.yourMessage' | translate }}</mat-label> <textarea matInput cdkTextareaAutosize #autosize="cdkTextareaAutosize" formControlName="message" maxlength="130"></textarea> </mat-form-field> <div class="buttons-right"> <button type="button" class="order-button" mat-raised-button color="primary" [xenNavigationDirective]="goBackHome['link']" [routerLink]="userRealm + goBackHome['route']" > <mat-icon>not_interested</mat-icon> {{ 'order.form.button.cancel' | translate }} </button> <button type="submit" class="order-button" mat-raised-button color="primary" [disabled]="!orderForm.valid" (click)="onSendOrders()" > <mat-icon>check</mat-icon> {{ 'order.form.button.sendOrder' | translate }} </button> </div> </div> </form>
现有TS提交方法
protected onSendOrders(): void { this.spinner.show(); let order: ICommande = { message: this.orderForm.get('message')?.value, detail: this.ordersFormArray.value }; this.order .sendOrders(order) .pipe( take(1), finalize(() => this.spinner.hide()) ) .subscribe({ next: () => { this.notification.success('order.form.message.sendOrderSuccess'); }, error: () => { this.notification.error('order.form.message.sendOrderFail'); } }); }
解决方案
方法一:修改提交按钮类型为button,手动触发表单验证
HTML中默认的type="submit"按钮会响应回车键触发表单提交,将其改为type="button"即可阻止该默认行为,同时在TS方法中手动触发表单验证:
- 修改提交按钮代码:
<button type="button" class="order-button" mat-raised-button color="primary" [disabled]="!orderForm.valid" (click)="onSendOrders()" > <mat-icon>check</mat-icon> {{ 'order.form.button.sendOrder' | translate }} </button>
- 在TS的
onSendOrders方法开头添加手动验证逻辑:
protected onSendOrders(): void { // 标记所有表单控件为已触碰,触发验证提示 this.orderForm.markAllAsTouched(); // 表单无效则直接返回 if (!this.orderForm.valid) { return; } this.spinner.show(); let order: ICommande = { message: this.orderForm.get('message')?.value, detail: this.ordersFormArray.value }; this.order .sendOrders(order) .pipe( take(1), finalize(() => this.spinner.hide()) ) .subscribe({ next: () => { this.notification.success('order.form.message.sendOrderSuccess'); }, error: () => { this.notification.error('order.form.message.sendOrderFail'); } }); }
方法二:阻止表单默认提交事件
如果希望保留按钮的type="submit"类型,可以在form标签上监听ngSubmit事件并阻止默认行为:
修改form标签:
<form [formGroup]="orderForm" (ngSubmit)="$event.preventDefault()">
这样回车键触发的表单提交会被阻止,只有点击按钮时才会执行onSendOrders方法。
原理说明
HTML表单的默认行为是:当表单内存在type="submit"的按钮时,按下回车键会自动触发表单的submit事件,进而触发Angular表单的验证逻辑。上述两种方法都是通过打破这个默认行为,让表单验证和提交仅由按钮点击触发。
内容的提问来源于stack exchange,提问作者Olivier
相关产品推荐
相关产品推荐

