mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-18 19:21:34 +08:00
feat(numeric-input): create number input control value accessor
This commit is contained in:
@ -0,0 +1,62 @@
|
||||
import { Directive, ElementRef, HostListener, Renderer2 } from '@angular/core';
|
||||
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||
|
||||
@Directive({
|
||||
/* tslint:disable-next-line:directive-selector */
|
||||
selector: 'ion-input[type=number]',
|
||||
providers: [
|
||||
{
|
||||
provide: NG_VALUE_ACCESSOR,
|
||||
useExisting: NumericValueAccessor,
|
||||
multi: true
|
||||
}
|
||||
]
|
||||
})
|
||||
export class NumericValueAccessor implements ControlValueAccessor {
|
||||
constructor(private element: ElementRef, private renderer: Renderer2) {
|
||||
this.onChange = () => {};
|
||||
this.onTouched = () => {};
|
||||
}
|
||||
|
||||
onChange: (value: any) => void;
|
||||
onTouched: () => void;
|
||||
|
||||
writeValue(value: any): void {
|
||||
// The value needs to be normalized for IE9, otherwise it is set to 'null' when null
|
||||
// Probably not an issue for us, but it doesn't really cost anything either
|
||||
const normalizedValue = value == null ? '' : value;
|
||||
this.renderer.setProperty(
|
||||
this.element.nativeElement,
|
||||
'value',
|
||||
normalizedValue
|
||||
);
|
||||
}
|
||||
|
||||
@HostListener('input', ['$event.target.value'])
|
||||
_handleInputEvent(value: any): void {
|
||||
this.onChange(value);
|
||||
}
|
||||
|
||||
@HostListener('ionBlur')
|
||||
_handleBlurEvent(): void {
|
||||
this.onTouched();
|
||||
}
|
||||
|
||||
registerOnChange(fn: (_: number | null) => void): void {
|
||||
this.onChange = value => {
|
||||
fn(value == '' ? null : parseFloat(value));
|
||||
};
|
||||
}
|
||||
|
||||
registerOnTouched(fn: () => void): void {
|
||||
this.onTouched = fn;
|
||||
}
|
||||
|
||||
setDisabledState(isDisabled: boolean): void {
|
||||
this.renderer.setProperty(
|
||||
this.element.nativeElement,
|
||||
'disabled',
|
||||
isDisabled
|
||||
);
|
||||
}
|
||||
}
|
@ -1,11 +1,9 @@
|
||||
import { Directive, ElementRef, HostListener, Renderer2 } from '@angular/core';
|
||||
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||
|
||||
// NOTE: May need to look at this to see if we need anything else:
|
||||
// https://github.com/angular/angular/blob/5.0.1/packages/forms/src/directives/default_value_accessor.ts#L33-L101
|
||||
@Directive({
|
||||
/* tslint:disable-next-line:directive-selector */
|
||||
selector: 'ion-input,ion-textarea',
|
||||
selector: 'ion-input:not([type=number]),ion-textarea',
|
||||
providers: [
|
||||
{
|
||||
provide: NG_VALUE_ACCESSOR,
|
||||
@ -44,4 +42,12 @@ export class TextValueAccessor implements ControlValueAccessor {
|
||||
registerOnTouched(fn: () => void) {
|
||||
this.onTouched = fn;
|
||||
}
|
||||
|
||||
setDisabledState(isDisabled: boolean): void {
|
||||
this.renderer.setProperty(
|
||||
this.element.nativeElement,
|
||||
'disabled',
|
||||
isDisabled
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import {
|
||||
} from '@angular/core';
|
||||
|
||||
import { BooleanValueAccessor } from './control-value-accessors/boolean-value-accessor';
|
||||
import { NumericValueAccessor } from './control-value-accessors/numeric-value-accesssor';
|
||||
import { RadioValueAccessor } from './control-value-accessors/radio-value-accessor';
|
||||
import { SelectValueAccessor } from './control-value-accessors/select-value-accessor';
|
||||
import { TextValueAccessor } from './control-value-accessors/text-value-accessor';
|
||||
@ -23,6 +24,7 @@ import { ToastController } from './providers/toast-controller';
|
||||
declarations: [
|
||||
BooleanValueAccessor,
|
||||
IonNavDelegate,
|
||||
NumericValueAccessor,
|
||||
RadioValueAccessor,
|
||||
SelectValueAccessor,
|
||||
TextValueAccessor
|
||||
@ -30,6 +32,7 @@ import { ToastController } from './providers/toast-controller';
|
||||
exports: [
|
||||
BooleanValueAccessor,
|
||||
IonNavDelegate,
|
||||
NumericValueAccessor,
|
||||
RadioValueAccessor,
|
||||
SelectValueAccessor,
|
||||
TextValueAccessor
|
||||
|
@ -30,6 +30,30 @@
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
|
||||
<ion-row>
|
||||
<ion-col>
|
||||
<h2>Numeric Input</h2>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
<ion-row>
|
||||
<ion-col>
|
||||
<ion-item>
|
||||
<ion-label>Ionic Numeric Input</ion-label>
|
||||
<ion-input type="number" id="ionNumberInput" name="ionNumberInput" [(ngModel)]="numberValue"></ion-input>
|
||||
</ion-item>
|
||||
</ion-col>
|
||||
<ion-col>
|
||||
<div>
|
||||
Value:
|
||||
<span id="numberOutput">{{numberValue}}</span>
|
||||
</div>
|
||||
<div>
|
||||
Type:
|
||||
<span id="numberOutputType">{{typeOf(numberValue)}}</span>
|
||||
</div>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
|
||||
<ion-row>
|
||||
<ion-col>
|
||||
<h2>Textarea Input</h2>
|
||||
@ -127,7 +151,8 @@
|
||||
<ion-col>
|
||||
<ion-item>
|
||||
<ion-label>Ionic Date</ion-label>
|
||||
<ion-datetime id="ionDatetimeInput" pickerFormat="YYYY-MM-DD HH:mm:ss" displayFormat="MM/DD/YYYY HH:mm:ss" name="ionDatetimeInput" [(ngModel)]="datetimeValue"></ion-datetime>
|
||||
<ion-datetime id="ionDatetimeInput" pickerFormat="YYYY-MM-DD HH:mm:ss" displayFormat="MM/DD/YYYY HH:mm:ss" name="ionDatetimeInput"
|
||||
[(ngModel)]="datetimeValue"></ion-datetime>
|
||||
</ion-item>
|
||||
</ion-col>
|
||||
<ion-col>
|
||||
|
@ -10,6 +10,7 @@ export class BasicInputsPageComponent implements OnInit {
|
||||
datetimeValue = '2017-11-18T14:17:45-06:00';
|
||||
textareaValue = 'This is the Textarea Input';
|
||||
textValue = 'This is the Text Input';
|
||||
numberValue = 1138;
|
||||
|
||||
checkboxValue = true;
|
||||
toggleValue = false;
|
||||
@ -17,4 +18,8 @@ export class BasicInputsPageComponent implements OnInit {
|
||||
constructor() {}
|
||||
|
||||
ngOnInit() {}
|
||||
|
||||
typeOf(v: any): string {
|
||||
return typeof v;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user