希望你一切都好。
我想知道如何管理(或阻止)表单特定部分的焦点。
我有这个
#sliderContainer
,其中包含 4 个表格。如果一种表格有效,我们将滑至另一种表格。
<div #sliderContainer class="relative w-full flex flex-grow overflow-hidden">
<app-id-form [configForm]="configForm" class="slideItem px-20 py-2"/>
<app-personal-info-form [configForm]="configForm" class="slideItem"/>
<app-medical-info-form [configForm]="configForm" class="slideItem px-20 py-2"/>
<app-emergency-contacts-info-form [configForm]="configForm" class="slideItem px-20 py-2"/>
</div>
问题在于,即使表单无效,如果按键盘上的“Tab”键,焦点也会切换到下一个表单的输入(这不是期望的行为)。
我想要的是防止用户仅通过按“Tab”进入下一个表单,或者至少将焦点仅保留在当前表单上。
我该怎么做?
附加信息: 在下面的附加信息中,您将了解我如何在滑动到新表单之前检查当前表单是否有效。
//...
// code omited for simplicity purpose
//...
@ViewChild('sliderContainer') sliderContainer!: ElementRef
// When we press next button
protected async nextForm(): Promise<void> {
const currentStep = await firstValueFrom(this.currentStep$)
const currentForm = this.configForm.get(currentStep.form)
if (currentForm!.invalid || currentForm!.pending) return currentForm?.markAllAsTouched()
this.store.dispatch(configActions.nextForm())
this.slide().then()
}
// slide to next form
async slide() {
const currentIndex = await firstValueFrom(this.currentStepIndex$)
this.sliderContainer
.nativeElement
.querySelectorAll('.slideItem')
.forEach((item: ElementRef) => this.renderer.setStyle(item, 'transform', `translateX(${-100 * currentIndex}%)`))
}
您可以使用CDK焦点陷阱,并将焦点设置到表单内的特定陷阱。焦点陷阱会将光标困在其中,因此向前/向后按 Tab 键不会退出陷阱。
import { Component, QueryList, ViewChildren } from '@angular/core';
import { CommonModule } from '@angular/common';
import { A11yModule, CdkTrapFocus } from '@angular/cdk/a11y';
@Component({
selector: 'app-root',
standalone: true,
imports: [CommonModule, A11yModule],
template: `
<div class="wrapper">
@for (i of [1,2,3]; track i) {
<div>
<h2>Section {{i}}</h2>
<div cdkTrapFocus>
<input type="text" />
<input type="text" />
<button (click)="next(i)">Next</button>
</div>
</div>
}
<div>
<h2>Done!</h2>
<div cdkTrapFocus>
<div tabindex="0"></div>
</div>
</div>
</div>
`
})
export class App {
@ViewChildren(CdkTrapFocus)
traps!: QueryList<CdkTrapFocus>;
next(id: number) {
this.traps.get(id)?.focusTrap.focusFirstTabbableElement();
}
}