Skip to content

Commit 28669ae

Browse files
authored
fix(module:inputnumber): validate inputnumber value & rewrite strategy (#230)
close #42 close #203
1 parent 74b2506 commit 28669ae

File tree

2 files changed

+107
-47
lines changed

2 files changed

+107
-47
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/* tslint:disable:no-unused-variable */
2+
import { async, TestBed, fakeAsync, tick } from '@angular/core/testing';
3+
import { Component } from '@angular/core';
4+
import { FormsModule } from '@angular/forms';
5+
import { By } from '@angular/platform-browser';
6+
import { NzInputNumberModule } from './nz-input-number.module';
7+
import { NzInputNumberComponent } from './nz-input-number.component';
8+
9+
describe('NzInputNumber', () => {
10+
let testComponent;
11+
let fixture;
12+
let debugElement;
13+
describe('input number test all', () => {
14+
beforeEach(async(() => {
15+
TestBed.configureTestingModule({
16+
imports : [ NzInputNumberModule, FormsModule ],
17+
declarations: [ NzInputNumberComponentSpecComponent ],
18+
providers : []
19+
}).compileComponents();
20+
}));
21+
22+
beforeEach(() => {
23+
fixture = TestBed.createComponent(NzInputNumberComponentSpecComponent);
24+
testComponent = fixture.debugElement.componentInstance;
25+
debugElement = fixture.debugElement.query(By.directive(NzInputNumberComponent));
26+
});
27+
it('should disabled up and down work', fakeAsync(() => {
28+
fixture.detectChanges();
29+
const handlerDownElement = debugElement.nativeElement.querySelector('.ant-input-number-handler-down');
30+
expect(handlerDownElement.classList.contains('ant-input-number-handler-down-disabled')).toBe(true);
31+
handlerDownElement.click();
32+
fixture.detectChanges();
33+
expect(testComponent.initValue).toBe(1);
34+
testComponent.initValue = 9;
35+
fixture.detectChanges();
36+
tick();
37+
const handlerUpElement = debugElement.nativeElement.querySelector('.ant-input-number-handler-up');
38+
handlerUpElement.click();
39+
fixture.detectChanges();
40+
expect(handlerUpElement.classList.contains('ant-input-number-handler-up-disabled')).toBe(true);
41+
expect(testComponent.initValue).toBe(10);
42+
}));
43+
it('should disable style work', () => {
44+
testComponent.isDisabled = true;
45+
fixture.detectChanges();
46+
expect(debugElement.nativeElement.classList.contains('ant-input-number-disabled')).toBe(true);
47+
});
48+
fit('should size style work', fakeAsync(() => {
49+
testComponent.size = 'large';
50+
tick();
51+
fixture.detectChanges();
52+
expect(debugElement.nativeElement.classList.contains('ant-input-number-lg')).toBe(true);
53+
testComponent.size = 'small';
54+
tick();
55+
fixture.detectChanges();
56+
expect(debugElement.nativeElement.classList.contains('ant-input-number-sm')).toBe(true);
57+
}));
58+
});
59+
});
60+
61+
/** Test component that contains an InputNumber. */
62+
63+
@Component({
64+
selector: 'nz-input-number-component-spec',
65+
template: `
66+
<nz-input-number [nzSize]="size" [(ngModel)]="initValue" [nzMin]="1" [nzMax]="10" [nzStep]="1" [nzDisabled]="isDisabled"></nz-input-number>
67+
`
68+
})
69+
export class NzInputNumberComponentSpecComponent {
70+
isDisabled = false;
71+
initValue = 1;
72+
size = 'default';
73+
}
74+
75+

Diff for: src/components/input-number/nz-input-number.component.ts

+32-47
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import {
44
Input,
55
ElementRef,
66
Renderer2,
7-
HostListener,
87
ViewChild,
98
HostBinding,
109
forwardRef
@@ -19,29 +18,29 @@ import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
1918
<div class="ant-input-number-handler-wrap">
2019
<a class="ant-input-number-handler ant-input-number-handler-up"
2120
[ngClass]="{'ant-input-number-handler-up-disabled':_disabledUp}"
22-
(mousedown)="_numberUp($event)">
21+
(click)="_numberUp($event)">
2322
<span
2423
class="ant-input-number-handler-up-inner"
2524
(click)="$event.preventDefault();"></span>
2625
</a>
2726
<a
2827
class="ant-input-number-handler ant-input-number-handler-down"
2928
[ngClass]="{'ant-input-number-handler-down-disabled':_disabledDown}"
30-
(mousedown)="_numberDown($event)">
29+
(click)="_numberDown($event)">
3130
<span
3231
class="ant-input-number-handler-down-inner"
3332
(click)="$event.preventDefault();">
3433
</span>
3534
</a>
3635
</div>
3736
<div
38-
#inputWrapper
3937
class="ant-input-number-input-wrap">
4038
<input class="ant-input-number-input"
4139
#inputNumber
40+
(blur)="_checkValue()"
4241
[placeholder]="nzPlaceHolder"
4342
[disabled]="nzDisabled"
44-
[(ngModel)]="nzValue"
43+
[(ngModel)]="_displayValue"
4544
(ngModelChange)="_userInputChange()"
4645
[attr.min]="nzMin"
4746
[attr.max]="nzMax"
@@ -64,16 +63,16 @@ export class NzInputNumberComponent implements ControlValueAccessor {
6463
_value: number;
6564
_size = 'default';
6665
_prefixCls = 'ant-input-number';
67-
_disabledUp = false;
68-
_disabledDown = false;
6966
_step = 1;
7067
_precisionStep = 0;
7168
_precisionFactor = 1;
69+
_displayValue;
70+
_disabledUp = false;
71+
_disabledDown = false;
7272
// ngModel Access
7373
onChange: any = Function.prototype;
7474
onTouched: any = Function.prototype;
7575
@ViewChild('inputNumber') _inputNumber: ElementRef;
76-
@ViewChild('inputWrapper') _inputWrapper: ElementRef;
7776

7877
@Input() nzPlaceHolder = '';
7978
@Input() nzMin: number = -Infinity;
@@ -109,30 +108,15 @@ export class NzInputNumberComponent implements ControlValueAccessor {
109108
this._precisionFactor = Math.pow(10, this._precisionStep);
110109
}
111110

112-
@HostListener('document:click', [ '$event.target' ])
113-
onClick(target) {
114-
if (target && !this._inputWrapper.nativeElement.contains(target)) {
115-
this._offClick();
116-
}
117-
}
118-
119-
_checkDisabled = () => {
120-
this._disabledUp = !((this.nzValue + this.nzStep) <= this.nzMax);
121-
this._disabledDown = !((this.nzValue - this.nzStep) >= this.nzMin);
122-
}
123-
124111
_numberUp($event) {
125112
$event.preventDefault();
126113
$event.stopPropagation();
127114
if (this.nzValue === undefined) {
128115
this.nzValue = this.nzMin || 0;
129116
}
130-
this._checkDisabled();
131117
if (!this._disabledUp) {
132118
this.nzValue = this.toPrecisionAsStep((this._precisionFactor * this.nzValue + this._precisionFactor * this.nzStep) / this._precisionFactor);
133119
}
134-
this._checkDisabled();
135-
this._userInputChange();
136120
}
137121

138122
_numberDown($event) {
@@ -141,12 +125,9 @@ export class NzInputNumberComponent implements ControlValueAccessor {
141125
if (this.nzValue === undefined) {
142126
this.nzValue = this.nzMin || 0;
143127
}
144-
this._checkDisabled();
145128
if (!this._disabledDown) {
146129
this.nzValue = this.toPrecisionAsStep((this._precisionFactor * this.nzValue - this._precisionFactor * this.nzStep) / this._precisionFactor);
147130
}
148-
this._checkDisabled();
149-
this._userInputChange();
150131
}
151132

152133
get nzValue(): number {
@@ -157,35 +138,39 @@ export class NzInputNumberComponent implements ControlValueAccessor {
157138
if (this._value === value) {
158139
return;
159140
}
160-
if (value > this.nzMax) {
161-
this._value = this.nzMax;
162-
this.onChange(this.nzMax);
163-
} else if (value < this.nzMin) {
164-
this._value = this.nzMin;
165-
this.onChange(this.nzMin);
166-
} else {
167-
this._value = value;
168-
this._checkDisabled();
169-
}
141+
this._value = this._getBoundValue(value);
142+
this._displayValue = this._value;
143+
this._inputNumber.nativeElement.value = this._value;
144+
this.onChange(this._value);
145+
this._disabledUp = (this.nzValue !== undefined) && !((this.nzValue + this.nzStep) <= this.nzMax);
146+
this._disabledDown = (this.nzValue !== undefined) && !((this.nzValue - this.nzStep) >= this.nzMin);
170147
}
171148

172149
_userInputChange() {
173-
this.onChange(this.nzValue);
150+
const numberValue = +this._displayValue;
151+
if (this._isNumber(numberValue) && (numberValue <= this.nzMax) && (numberValue >= this.nzMin)) {
152+
this.nzValue = numberValue;
153+
}
174154
}
175155

176-
_offClick() {
177-
if (this._value === undefined) {
178-
return;
179-
}
180-
if (this._inputNumber.nativeElement.value > this.nzMax) {
181-
this._inputNumber.nativeElement.value = this.nzMax;
182-
this.onChange(this.nzMax);
183-
} else if (this._inputNumber.nativeElement.value < this.nzMin) {
184-
this._inputNumber.nativeElement.value = this.nzMin;
185-
this.onChange(this.nzMin);
156+
_checkValue() {
157+
this._displayValue = this.nzValue;
158+
}
159+
160+
_getBoundValue(value) {
161+
if (value > this.nzMax) {
162+
return this.nzMax;
163+
} else if (value < this.nzMin) {
164+
return this.nzMin;
165+
} else {
166+
return value;
186167
}
187168
}
188169

170+
_isNumber(value) {
171+
return !isNaN(value) && isFinite(value)
172+
}
173+
189174
toPrecisionAsStep(num) {
190175
if (isNaN(num) || num === '') {
191176
return num;

0 commit comments

Comments
 (0)