diff --git a/packages/angular/src/control-value-accessors/numeric-value-accesssor.ts b/packages/angular/src/control-value-accessors/numeric-value-accesssor.ts new file mode 100644 index 0000000000..9fd4a4ac89 --- /dev/null +++ b/packages/angular/src/control-value-accessors/numeric-value-accesssor.ts @@ -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 + ); + } +} diff --git a/packages/angular/src/control-value-accessors/text-value-accessor.ts b/packages/angular/src/control-value-accessors/text-value-accessor.ts index bc8ef44f1c..a015223bc8 100644 --- a/packages/angular/src/control-value-accessors/text-value-accessor.ts +++ b/packages/angular/src/control-value-accessors/text-value-accessor.ts @@ -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 + ); + } } diff --git a/packages/angular/src/module.ts b/packages/angular/src/module.ts index d52da78332..edbe1a5975 100644 --- a/packages/angular/src/module.ts +++ b/packages/angular/src/module.ts @@ -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 diff --git a/packages/demos/angular/src/app/basic-inputs-page/basic-inputs-page.component.html b/packages/demos/angular/src/app/basic-inputs-page/basic-inputs-page.component.html index 5e28577a08..05526bb451 100644 --- a/packages/demos/angular/src/app/basic-inputs-page/basic-inputs-page.component.html +++ b/packages/demos/angular/src/app/basic-inputs-page/basic-inputs-page.component.html @@ -30,6 +30,30 @@ + + + Numeric Input + + + + + + Ionic Numeric Input + + + + + + Value: + {{numberValue}} + + + Type: + {{typeOf(numberValue)}} + + + + Textarea Input @@ -127,7 +151,8 @@ Ionic Date - + diff --git a/packages/demos/angular/src/app/basic-inputs-page/basic-inputs-page.component.ts b/packages/demos/angular/src/app/basic-inputs-page/basic-inputs-page.component.ts index b8ec11a5ab..fccec8ba2c 100644 --- a/packages/demos/angular/src/app/basic-inputs-page/basic-inputs-page.component.ts +++ b/packages/demos/angular/src/app/basic-inputs-page/basic-inputs-page.component.ts @@ -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; + } }