From 85b8bffaa67b5e942fdf43f189f9696277b30ed3 Mon Sep 17 00:00:00 2001 From: Yadong Xie Date: Fri, 11 Oct 2019 11:20:07 +0800 Subject: [PATCH] fix(module:select): fix select focus & blur & autoFocus event (#4270) close #3991 close #3757 close #3708 --- components/select/nz-select.component.html | 2 + components/select/nz-select.component.spec.ts | 20 ++----- components/select/nz-select.component.ts | 52 ++++++++----------- 3 files changed, 29 insertions(+), 45 deletions(-) diff --git a/components/select/nz-select.component.html b/components/select/nz-select.component.html index 8fc41dacaa3..db30d800228 100644 --- a/components/select/nz-select.component.html +++ b/components/select/nz-select.component.html @@ -19,6 +19,8 @@ [nzTokenSeparators]="nzTokenSeparators" [class.ant-select-selection--single]="nzSelectService.isSingleMode" [class.ant-select-selection--multiple]="nzSelectService.isMultipleOrTags" + (focus)="onFocus()" + (blur)="onBlur()" (keydown)="onKeyDown($event)"> { expect(testComponent.open).toBe(false); expect(testComponent.openChange).toHaveBeenCalledTimes(0); })); - it('should autofocus work', () => { - testComponent.showSearch = true; - fixture.detectChanges(); - testComponent.autoFocus = true; - fixture.detectChanges(); - expect(select.nativeElement.querySelector('input').attributes.getNamedItem('autofocus').name).toBe('autofocus'); - testComponent.autoFocus = false; - fixture.detectChanges(); - expect(select.nativeElement.querySelector('input').attributes.getNamedItem('autofocus')).toBe(null); - }); it('should focus and blur function work', () => { testComponent.showSearch = true; select.nativeElement.click(); fixture.detectChanges(); - expect(select.nativeElement.querySelector('input') === document.activeElement).toBe(false); - selectComponent.focus(); - fixture.detectChanges(); - expect(select.nativeElement.querySelector('input') === document.activeElement).toBe(true); + expect(select.nativeElement.querySelector('.ant-select-selection') === document.activeElement).toBe(true); selectComponent.blur(); fixture.detectChanges(); - expect(select.nativeElement.querySelector('input') === document.activeElement).toBe(false); + expect(select.nativeElement.querySelector('.ant-select-selection') === document.activeElement).toBe(false); + selectComponent.focus(); + fixture.detectChanges(); + expect(select.nativeElement.querySelector('.ant-select-selection') === document.activeElement).toBe(true); }); it('should dropdown class work', () => { fixture.detectChanges(); diff --git a/components/select/nz-select.component.ts b/components/select/nz-select.component.ts index 8b7de3b68a1..f1380a25d6f 100644 --- a/components/select/nz-select.component.ts +++ b/components/select/nz-select.component.ts @@ -6,7 +6,6 @@ * found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE */ -import { FocusMonitor } from '@angular/cdk/a11y'; import { CdkConnectedOverlay, CdkOverlayOrigin, ConnectedOverlayPositionChange } from '@angular/cdk/overlay'; import { Platform } from '@angular/cdk/platform'; import { @@ -98,12 +97,12 @@ export class NzSelectComponent implements ControlValueAccessor, OnInit, AfterVie dropDownPosition: 'top' | 'center' | 'bottom' = 'bottom'; triggerWidth: number; private _disabled = false; - private _autoFocus = false; private isInit = false; private destroy$ = new Subject(); @ViewChild(CdkOverlayOrigin, { static: false }) cdkOverlayOrigin: CdkOverlayOrigin; @ViewChild(CdkConnectedOverlay, { static: false }) cdkConnectedOverlay: CdkConnectedOverlay; @ViewChild(NzSelectTopControlComponent, { static: true }) nzSelectTopControlComponent: NzSelectTopControlComponent; + @ViewChild(NzSelectTopControlComponent, { static: true, read: ElementRef }) nzSelectTopControlElement: ElementRef; /** should move to nz-option-container when https://github.com/angular/angular/issues/20810 resolved **/ @ContentChildren(NzOptionComponent) listOfNzOptionComponent: QueryList; @ContentChildren(NzOptionGroupComponent) listOfNzOptionGroupComponent: QueryList; @@ -120,6 +119,7 @@ export class NzSelectComponent implements ControlValueAccessor, OnInit, AfterVie @Input() @InputBoolean() nzAllowClear = false; @Input() @InputBoolean() nzShowSearch = false; @Input() @InputBoolean() nzLoading = false; + @Input() @InputBoolean() nzAutoFocus = false; @Input() nzPlaceHolder: string; @Input() nzMaxTagCount: number; @Input() nzDropdownRender: TemplateRef; @@ -165,16 +165,6 @@ export class NzSelectComponent implements ControlValueAccessor, OnInit, AfterVie this.nzSelectService.compareWith = value; } - @Input() - set nzAutoFocus(value: boolean) { - this._autoFocus = toBoolean(value); - this.updateAutoFocus(); - } - - get nzAutoFocus(): boolean { - return this._autoFocus; - } - @Input() set nzOpen(value: boolean) { this.open = value; @@ -195,34 +185,36 @@ export class NzSelectComponent implements ControlValueAccessor, OnInit, AfterVie return this._disabled; } + get nzSelectTopControlDOM(): HTMLElement { + return this.nzSelectTopControlElement && this.nzSelectTopControlElement.nativeElement; + } + updateAutoFocus(): void { - if (this.nzSelectTopControlComponent.inputElement) { - if (this.nzAutoFocus) { - this.renderer.setAttribute( - this.nzSelectTopControlComponent.inputElement.nativeElement, - 'autofocus', - 'autofocus' - ); - } else { - this.renderer.removeAttribute(this.nzSelectTopControlComponent.inputElement.nativeElement, 'autofocus'); - } + if (this.nzSelectTopControlDOM && this.nzAutoFocus) { + this.nzSelectTopControlDOM.focus(); } } focus(): void { - if (this.nzSelectTopControlComponent.inputElement) { - this.focusMonitor.focusVia(this.nzSelectTopControlComponent.inputElement, 'keyboard'); - this.nzFocus.emit(); + if (this.nzSelectTopControlDOM) { + this.nzSelectTopControlDOM.focus(); } } blur(): void { - if (this.nzSelectTopControlComponent.inputElement) { - this.nzSelectTopControlComponent.inputElement.nativeElement.blur(); - this.nzBlur.emit(); + if (this.nzSelectTopControlDOM) { + this.nzSelectTopControlDOM.blur(); } } + onFocus(): void { + this.nzFocus.emit(); + } + + onBlur(): void { + this.nzBlur.emit(); + } + onKeyDown(event: KeyboardEvent): void { this.nzSelectService.onKeyDown(event); } @@ -256,10 +248,9 @@ export class NzSelectComponent implements ControlValueAccessor, OnInit, AfterVie } constructor( - private renderer: Renderer2, + renderer: Renderer2, public nzSelectService: NzSelectService, private cdr: ChangeDetectorRef, - private focusMonitor: FocusMonitor, private platform: Platform, elementRef: ElementRef, @Host() @Optional() public noAnimation?: NzNoAnimationDirective @@ -331,6 +322,7 @@ export class NzSelectComponent implements ControlValueAccessor, OnInit, AfterVie ngAfterViewInit(): void { this.updateCdkConnectedOverlayStatus(); + this.updateAutoFocus(); this.isInit = true; }