管理或阻止对特定表单的关注

问题描述 投票:0回答:1

希望你一切都好。

我想知道如何管理(或阻止)表单特定部分的焦点。

我有这个

#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}%)`))
  }
angular typescript input focus
1个回答
0
投票

您可以使用CDK焦点陷阱,并将焦点设置到表单内的特定陷阱。焦点陷阱会将光标困在其中,因此向前/向后按 Tab 键不会退出陷阱。

Stackblitz 示例

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();
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.