Skip to content

Commit

Permalink
fix: some forms component can't be disable (#7786)
Browse files Browse the repository at this point in the history
* fix(module:date-picker): nzDatePicker can be always disable

* fix(module:checkbox): 🐛 checkbox can be always disable or enable

* fix(module:input-number): input-number can be always disable or enable

* fix(module:rate): rate can be always disable or enable

* fix(module:radio): radio can be always disable or enable

* fix(module:select): radio can be always disable or enable

* fix(module:checkbox): checkbox can be always disable or enable

* fix(module:slider): slider can be always disable or enable

* fix(module:time-picker): time-picker can be always disable or enable

* refactor(module:cascader): close the menu based on nzDisable property

* test(module:checkbox): add missing test on disable behavior with forms

* test(module:radio): add missing test on disable behavior with forms

* test(module:switch): add missing test on disable behavior with forms

* chore: bump custom webpack to v15

* test(module:rate): add missing test on disable behavior with forms

* test(module:input-number): add missing test on disable behavior

* test(module:select): add missing test on disable behavior

* test(module:checkbox): refactor test

* test(module:switch): refactor test

* test(module:radio): add missing test on disable behavior with forms

* test(module:rate): add missing test on disable behavior with forms

* test: refactor some test

* test(module:slider): add missing test on disable behavior with forms

* test(module:timepicker): add missing test on disable behavior

* test(module:datepicker): add missing test on disable behavior
  • Loading branch information
Nicoss54 authored Jan 9, 2023
1 parent 285655a commit bc673e7
Show file tree
Hide file tree
Showing 20 changed files with 446 additions and 160 deletions.
6 changes: 3 additions & 3 deletions components/cascader/cascader.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -747,11 +747,11 @@ export class NzCascaderComponent
}

setDisabledState(isDisabled: boolean): void {
if (isDisabled) {
this.closeMenu();
}
this.nzDisabled = (this.isNzDisableFirstChange && this.nzDisabled) || isDisabled;
this.isNzDisableFirstChange = false;
if (this.nzDisabled) {
this.closeMenu();
}
}

closeMenu(): void {
Expand Down
4 changes: 3 additions & 1 deletion components/checkbox/checkbox.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ export class NzCheckboxComponent implements OnInit, ControlValueAccessor, OnDest

dir: Direction = 'ltr';
private destroy$ = new Subject<void>();
private isNzDisableFirstChange: boolean = true;

onChange: OnChangeType = () => {};
onTouched: OnTouchedType = () => {};
Expand Down Expand Up @@ -119,7 +120,8 @@ export class NzCheckboxComponent implements OnInit, ControlValueAccessor, OnDest
}

setDisabledState(disabled: boolean): void {
this.nzDisabled = disabled;
this.nzDisabled = (this.isNzDisableFirstChange && this.nzDisabled) || disabled;
this.isNzDisableFirstChange = false;
this.cdr.markForCheck();
}

Expand Down
57 changes: 45 additions & 12 deletions components/checkbox/checkbox.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { BidiModule, Dir } from '@angular/cdk/bidi';
import { ApplicationRef, Component, DebugElement, ViewChild } from '@angular/core';
import { ComponentFixture, fakeAsync, flush, TestBed, waitForAsync } from '@angular/core/testing';
import { UntypedFormBuilder, UntypedFormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms';
import { FormsModule, ReactiveFormsModule, UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
import { By } from '@angular/platform-browser';

import { NzCheckboxGroupComponent } from './checkbox-group.component';
Expand Down Expand Up @@ -221,32 +221,60 @@ describe('checkbox', () => {
describe('checkbox form', () => {
let fixture: ComponentFixture<NzTestCheckboxFormComponent>;
let testComponent: NzTestCheckboxFormComponent;
let checkbox: DebugElement;
let inputElement: HTMLInputElement;

beforeEach(fakeAsync(() => {
beforeEach(() => {
fixture = TestBed.createComponent(NzTestCheckboxFormComponent);
testComponent = fixture.componentInstance;
});
it('should be in pristine, untouched, and valid states and enable initially', fakeAsync(() => {
fixture.detectChanges();
flush();
fixture.detectChanges();
testComponent = fixture.debugElement.componentInstance;
checkbox = fixture.debugElement.query(By.directive(NzCheckboxComponent));
inputElement = checkbox.nativeElement.querySelector('input') as HTMLInputElement;
}));
it('should be in pristine, untouched, and valid states initially', fakeAsync(() => {
flush();
const checkbox = fixture.debugElement.query(By.directive(NzCheckboxComponent));
const inputElement = checkbox.nativeElement.querySelector('input') as HTMLInputElement;
expect(checkbox.nativeElement.firstElementChild!.classList).not.toContain('ant-checkbox-disabled');
expect(inputElement.disabled).toBeFalsy();
expect(testComponent.formGroup.valid).toBe(true);
expect(testComponent.formGroup.pristine).toBe(true);
expect(testComponent.formGroup.touched).toBe(false);
}));
it('should be disable if form is disable and nzDisable set to false', fakeAsync(() => {
testComponent.disable();
fixture.detectChanges();
flush();
const checkbox = fixture.debugElement.query(By.directive(NzCheckboxComponent));
const inputElement = checkbox.nativeElement.querySelector('input') as HTMLInputElement;
expect(checkbox.nativeElement.firstElementChild!.classList).toContain('ant-checkbox-disabled');
expect(inputElement.disabled).toBeTruthy();
}));
it('should set disabled work', fakeAsync(() => {
testComponent.disabled = true;
fixture.detectChanges();
flush();
const checkbox = fixture.debugElement.query(By.directive(NzCheckboxComponent));
const inputElement = checkbox.nativeElement.querySelector('input') as HTMLInputElement;

expect(checkbox.nativeElement.firstElementChild!.classList).toContain('ant-checkbox-disabled');
expect(inputElement.disabled).toBeTruthy();
inputElement.click();
flush();
fixture.detectChanges();
expect(testComponent.formGroup.get('checkbox')!.value).toBe(false);

testComponent.enable();
fixture.detectChanges();
flush();
expect(checkbox.nativeElement.firstElementChild!.classList).not.toContain('ant-checkbox-disabled');
expect(inputElement.disabled).toBeFalsy();
inputElement.click();
flush();
fixture.detectChanges();
expect(testComponent.formGroup.get('checkbox')!.value).toBe(true);

testComponent.disable();
fixture.detectChanges();
flush();
expect(checkbox.nativeElement.firstElementChild!.classList).toContain('ant-checkbox-disabled');
expect(inputElement.disabled).toBeTruthy();
inputElement.click();
flush();
fixture.detectChanges();
Expand Down Expand Up @@ -425,12 +453,13 @@ export class NzTestCheckboxWrapperComponent {
@Component({
template: `
<form [formGroup]="formGroup">
<label nz-checkbox formControlName="checkbox"></label>
<label nz-checkbox formControlName="checkbox" [nzDisabled]="disabled"></label>
</form>
`
})
export class NzTestCheckboxFormComponent {
formGroup: UntypedFormGroup;
disabled = false;

constructor(private formBuilder: UntypedFormBuilder) {
this.formGroup = this.formBuilder.group({
Expand All @@ -441,6 +470,10 @@ export class NzTestCheckboxFormComponent {
disable(): void {
this.formGroup.disable();
}

enable(): void {
this.formGroup.enable();
}
}

@Component({
Expand Down
49 changes: 38 additions & 11 deletions components/date-picker/date-picker.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ import zh from '@angular/common/locales/zh';
import { ApplicationRef, Component, DebugElement, TemplateRef, ViewChild } from '@angular/core';
import { ComponentFixture, fakeAsync, flush, inject, TestBed, tick } from '@angular/core/testing';
import {
FormControl,
FormsModule,
ReactiveFormsModule,
UntypedFormBuilder,
UntypedFormControl,
UntypedFormGroup,
FormsModule,
ReactiveFormsModule,
Validators
} from '@angular/forms';
import { By } from '@angular/platform-browser';
Expand Down Expand Up @@ -271,22 +272,43 @@ describe('NzDatePickerComponent', () => {
});

it('should support nzDisabled', fakeAsync(() => {
// Make sure picker clear button shown up
fixtureInstance.nzAllowClear = true;
fixtureInstance.useSuite = 4;
fixtureInstance.nzDisabled = true;
fixtureInstance.nzAllowClear = true; // Make sure picker clear button shown up
fixtureInstance.nzValue = new Date();
fixtureInstance.control = new FormControl(new Date());
fixture.detectChanges();
flush();

fixtureInstance.nzDisabled = true;
const datePickerElement = fixture.debugElement.query(By.directive(NzDatePickerComponent)).nativeElement;
const inputElement = fixture.debugElement.query(By.css('input')).nativeElement as HTMLInputElement;

expect(datePickerElement.classList).toContain('ant-picker-disabled');
expect(inputElement.disabled).toBeTruthy();
openPickerByClickTrigger();
expect(getPickerContainer()).toBeNull();

fixtureInstance.control.enable();
fixture.detectChanges();
flush();
fixture.detectChanges();
expect(debugElement.query(By.css('.ant-input-disabled'))).not.toBeNull();
expect(debugElement.query(By.css('.ant-picker-clear'))).toBeNull();
expect(datePickerElement.classList).not.toContain('ant-picker-disabled');
expect(inputElement.disabled).toBeFalsy();
openPickerByClickTrigger();
expect(getPickerContainer()).not.toBeNull();

fixtureInstance.nzDisabled = false;
dispatchKeyboardEvent(document.body, 'keydown', ESCAPE);
fixture.detectChanges();
tick(500);
fixture.detectChanges();
expect(debugElement.query(By.css('.ant-input-disabled'))).toBeNull();
expect(debugElement.query(By.css('.ant-picker-clear'))).not.toBeNull();
fixtureInstance.control.disable();
fixture.detectChanges();
flush();
fixture.detectChanges();
expect(datePickerElement.classList).toContain('ant-picker-disabled');
expect(inputElement.disabled).toBeTruthy();
openPickerByClickTrigger();
expect(getPickerContainer()).toBeNull();
}));

it('should support nzInputReadOnly', fakeAsync(() => {
Expand Down Expand Up @@ -1199,6 +1221,11 @@ describe('NzDatePickerComponent', () => {
fixture.detectChanges();
flush(); // Wait writeValue() tobe done
fixture.detectChanges();
const datePickerElement = fixture.debugElement.query(By.directive(NzDatePickerComponent)).nativeElement;
const inputElement = fixture.debugElement.query(By.css('input')).nativeElement as HTMLInputElement;

expect(datePickerElement.classList).not.toContain('ant-picker-disabled');
expect(inputElement.disabled).toBeFalsy();
expect(getPickerInput(fixture.debugElement).value!.trim()).toBe('2020-04-08');
}));

Expand Down Expand Up @@ -1405,7 +1432,7 @@ describe('in form', () => {
<nz-date-picker *ngSwitchCase="3" nzOpen [(ngModel)]="modelValue"></nz-date-picker>
<!-- Suite 4 -->
<nz-date-picker *ngSwitchCase="4" [formControl]="control"></nz-date-picker>
<nz-date-picker *ngSwitchCase="4" [formControl]="control" [nzDisabled]="nzDisabled"></nz-date-picker>
<!-- Suite 5 -->
<ng-container *ngSwitchCase="5">
Expand Down
2 changes: 1 addition & 1 deletion components/date-picker/date-picker.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -768,7 +768,7 @@ export class NzDatePickerComponent implements OnInit, OnChanges, OnDestroy, Afte
setDisabledState(isDisabled: boolean): void {
this.nzDisabled = (this.isNzDisableFirstChange && this.nzDisabled) || isDisabled;
this.cdr.markForCheck();
this.isNzDisableFirstChange = true;
this.isNzDisableFirstChange = false;
}

// ------------------------------------------------------------------------
Expand Down
6 changes: 4 additions & 2 deletions components/input-number/input-number.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ export class NzInputNumberComponent implements ControlValueAccessor, AfterViewIn
private autoStepTimer?: number;
private parsedValue?: string | number;
private value?: number;
private isNzDisableFirstChange: boolean = true;
displayValue?: string | number;
isFocused = false;
disabled$ = new Subject<boolean>();
Expand Down Expand Up @@ -386,8 +387,9 @@ export class NzInputNumberComponent implements ControlValueAccessor, AfterViewIn
}

setDisabledState(disabled: boolean): void {
this.nzDisabled = disabled;
this.disabled$.next(disabled);
this.nzDisabled = (this.isNzDisableFirstChange && this.nzDisabled) || disabled;
this.isNzDisableFirstChange = false;
this.disabled$.next(this.nzDisabled);
this.cdr.markForCheck();
}

Expand Down
59 changes: 44 additions & 15 deletions components/input-number/input-number.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { DOWN_ARROW, ENTER, TAB, UP_ARROW } from '@angular/cdk/keycodes';
import { ApplicationRef, Component, DebugElement, NgZone, ViewChild } from '@angular/core';
import { ComponentFixture, fakeAsync, flush, TestBed, tick } from '@angular/core/testing';
import { UntypedFormBuilder, UntypedFormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms';
import { FormsModule, ReactiveFormsModule, UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
import { By } from '@angular/platform-browser';
import { take } from 'rxjs/operators';

Expand Down Expand Up @@ -464,39 +464,64 @@ describe('input number', () => {
describe('input number form', () => {
let fixture: ComponentFixture<NzTestInputNumberFormComponent>;
let testComponent: NzTestInputNumberFormComponent;
let inputNumber: DebugElement;
let upHandler: HTMLElement;

beforeEach(fakeAsync(() => {
beforeEach(() => {
fixture = TestBed.createComponent(NzTestInputNumberFormComponent);
testComponent = fixture.componentInstance;
});
it('should be in pristine, untouched, and valid states and be enable initially', fakeAsync(() => {
fixture.detectChanges();
flush();
fixture.detectChanges();
testComponent = fixture.debugElement.componentInstance;
inputNumber = fixture.debugElement.query(By.directive(NzInputNumberComponent));
upHandler = inputNumber.nativeElement.querySelector('.ant-input-number-handler-up');
}));
it('should be in pristine, untouched, and valid states initially', fakeAsync(() => {
flush();
const inputNumber = fixture.debugElement.query(By.directive(NzInputNumberComponent));
const inputElement = fixture.debugElement.query(By.css('input')).nativeElement as HTMLInputElement;
expect(inputNumber.nativeElement.classList).not.toContain('ant-input-number-disabled');
expect(inputElement.disabled).toBeFalsy();
expect(testComponent.formGroup.valid).toBe(true);
expect(testComponent.formGroup.pristine).toBe(true);
expect(testComponent.formGroup.touched).toBe(false);
}));
it('should set disabled work', fakeAsync(() => {
it('should be disable if form disable and nzDisabled set to false initially', fakeAsync(() => {
testComponent.disable();
fixture.detectChanges();
flush();
const inputNumber = fixture.debugElement.query(By.directive(NzInputNumberComponent));
const inputElement = fixture.debugElement.query(By.css('input')).nativeElement as HTMLInputElement;
expect(inputNumber.nativeElement.classList).toContain('ant-input-number-disabled');
expect(inputElement.disabled).toBeTruthy();
}));
it('should set disabled work', fakeAsync(() => {
testComponent.disabled = true;
fixture.detectChanges();
flush();
const inputNumber = fixture.debugElement.query(By.directive(NzInputNumberComponent));
const inputElement = fixture.debugElement.query(By.css('input')).nativeElement as HTMLInputElement;
const upHandler = inputNumber.nativeElement.querySelector('.ant-input-number-handler-up');
expect(inputNumber.nativeElement.classList).toContain('ant-input-number-disabled');
expect(inputElement.disabled).toBeTruthy();
expect(testComponent.formGroup.get('inputNumber')!.value).toBe(1);
dispatchFakeEvent(upHandler, 'mousedown');
fixture.detectChanges();
flush();
expect(testComponent.formGroup.get('inputNumber')!.value).toBe(1);

testComponent.enable();
fixture.detectChanges();
flush();
expect(inputNumber.nativeElement.classList).not.toContain('ant-input-number-disabled');
expect(inputElement.disabled).toBeFalsy();
dispatchFakeEvent(upHandler, 'mousedown');
fixture.detectChanges();
flush();
expect(testComponent.formGroup.get('inputNumber')!.value).toBe(10);

testComponent.disable();
dispatchFakeEvent(upHandler, 'mousedown');
fixture.detectChanges();
flush();
expect(inputNumber.nativeElement.classList).toContain('ant-input-number-disabled');
expect(inputElement.disabled).toBeTruthy();
dispatchFakeEvent(upHandler, 'mousedown');
fixture.detectChanges();
flush();
expect(testComponent.formGroup.get('inputNumber')!.value).toBe(10);
}));
});
Expand Down Expand Up @@ -598,7 +623,6 @@ describe('input number', () => {
});
});
});

@Component({
template: `
<nz-input-number
Expand Down Expand Up @@ -648,12 +672,13 @@ export class NzTestReadOnlyInputNumberBasicComponent {
@Component({
template: `
<form [formGroup]="formGroup">
<nz-input-number formControlName="inputNumber" nzMax="10" nzMin="-10"></nz-input-number>
<nz-input-number formControlName="inputNumber" nzMax="10" nzMin="-10" [nzDisabled]="disabled"></nz-input-number>
</form>
`
})
export class NzTestInputNumberFormComponent {
formGroup: UntypedFormGroup;
disabled = false;

constructor(private formBuilder: UntypedFormBuilder) {
this.formGroup = this.formBuilder.group({
Expand All @@ -664,6 +689,10 @@ export class NzTestInputNumberFormComponent {
disable(): void {
this.formGroup.disable();
}

enable(): void {
this.formGroup.enable();
}
}

@Component({
Expand Down
4 changes: 3 additions & 1 deletion components/radio/radio.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ export class NzRadioComponent implements ControlValueAccessor, AfterViewInit, On

private isNgModel = false;
private destroy$ = new Subject<void>();
private isNzDisableFirstChange: boolean = true;
isChecked = false;
name: string | null = null;
isRadioButton = !!this.nzRadioButtonDirective;
Expand Down Expand Up @@ -118,7 +119,8 @@ export class NzRadioComponent implements ControlValueAccessor, AfterViewInit, On
) {}

setDisabledState(disabled: boolean): void {
this.nzDisabled = disabled;
this.nzDisabled = (this.isNzDisableFirstChange && this.nzDisabled) || disabled;
this.isNzDisableFirstChange = false;
this.cdr.markForCheck();
}

Expand Down
Loading

0 comments on commit bc673e7

Please sign in to comment.