From 9469b4ff9afd478c6919294fafbbf2d23caf2bc6 Mon Sep 17 00:00:00 2001 From: Max Lynch Date: Wed, 16 Nov 2016 16:42:48 -0600 Subject: [PATCH] feat(input): clearOnEdit feature. Closes #9187 --- src/components/input/input-base.ts | 61 +++++++++++++++++++ src/components/input/input.ts | 17 ++++++ src/components/input/native-input.ts | 8 +++ .../input/test/clear-after-edit/app-module.ts | 33 ++++++++++ .../input/test/clear-after-edit/e2e.ts | 0 .../input/test/clear-after-edit/main.html | 24 ++++++++ 6 files changed, 143 insertions(+) create mode 100644 src/components/input/test/clear-after-edit/app-module.ts create mode 100644 src/components/input/test/clear-after-edit/e2e.ts create mode 100644 src/components/input/test/clear-after-edit/main.html diff --git a/src/components/input/input-base.ts b/src/components/input/input-base.ts index 2eb3f1de7fd..560dbe0fc8e 100644 --- a/src/components/input/input-base.ts +++ b/src/components/input/input-base.ts @@ -32,6 +32,11 @@ export class InputBase extends Ion { _nav: NavControllerBase; _native: NativeInput; + // Whether to clear after the user returns to the input and resumes editing + _clearOnEdit: boolean; + // A tracking flag to watch for the blur after editing to help with clearOnEdit + _didBlurAfterEdit: boolean; + inputControl: NgControl; constructor( @@ -133,6 +138,33 @@ export class InputBase extends Ion { this._native && this._native.isDisabled(this._disabled); } + setClearOnEdit(val: boolean) { + this._clearOnEdit = isTrueProperty(val); + } + + /** + * Check if we need to clear the text input if clearOnEdit is enabled + * @private + */ + checkClearOnEdit(inputValue: string) { + if(!this._clearOnEdit) { return; } + + // Did the input value change after it was blurred and edited? + if (this._didBlurAfterEdit && this.hasValue()) { + // Clear the input + this.clearTextInput(); + } + + // Reset the flag + this._didBlurAfterEdit = false; + } + + /** + * Overriden in child input + * @private + */ + clearTextInput() {} + /** * @private */ @@ -147,6 +179,10 @@ export class InputBase extends Ion { this.onChange(inputValue); }); + nativeInput.keydown.subscribe((inputValue: any) => { + this.onKeydown(inputValue); + }); + this.focusChange(this.hasFocus()); nativeInput.focusChange.subscribe((textInputHasFocus: any) => { this.focusChange(textInputHasFocus); @@ -228,6 +264,16 @@ export class InputBase extends Ion { this.checkHasValue(val); } + /** + * onKeydown handler for clearOnEdit + * @private + */ + onKeydown(val: any) { + if(this._clearOnEdit) { + this.checkClearOnEdit(val); + } + } + /** * @private */ @@ -241,12 +287,21 @@ export class InputBase extends Ion { return this._native.hasFocus(); } + /** + * @private + */ + hasValue(): boolean { + let inputValue = this._value; + return (inputValue !== null && inputValue !== undefined && inputValue !== ''); + } + /** * @private */ checkHasValue(inputValue: any) { if (this._item) { let hasValue = (inputValue !== null && inputValue !== undefined && inputValue !== ''); + this._item.setElementClass('input-has-value', hasValue); } } @@ -260,6 +315,12 @@ export class InputBase extends Ion { } if (!inputHasFocus) { this.deregScrollMove(); + + } + + // If clearOnEdit is enabled and the input blurred but has a value, set a flag + if(this._clearOnEdit && !inputHasFocus && this.hasValue()) { + this._didBlurAfterEdit = true; } } diff --git a/src/components/input/input.ts b/src/components/input/input.ts index 95ace7a45cd..66c46ae4667 100644 --- a/src/components/input/input.ts +++ b/src/components/input/input.ts @@ -160,6 +160,18 @@ export class TextInput extends InputBase { this._setMode(val); } + /** + * @input {boolean} whether to clear the input upon editing or not + */ + @Input() + get clearOnEdit() { + return this._clearOnEdit; + } + set clearOnEdit(val: any) { + super.setClearOnEdit(val); + } + + /** * @private */ @@ -207,6 +219,11 @@ export class TextInput extends InputBase { this._item.setElementClass('item-input', true); this._item.registerInput(this._type); } + + // By default, password inputs clear after focus when they have content + if(this.type === 'password' && this.clearOnEdit !== false) { + this.clearOnEdit = true; + } } /** diff --git a/src/components/input/native-input.ts b/src/components/input/native-input.ts index 3d8c70db45f..8b4734cc6f0 100644 --- a/src/components/input/native-input.ts +++ b/src/components/input/native-input.ts @@ -19,6 +19,7 @@ export class NativeInput { @Output() focusChange: EventEmitter = new EventEmitter(); @Output() valueChange: EventEmitter = new EventEmitter(); + @Output() keydown: EventEmitter = new EventEmitter(); constructor( public _elementRef: ElementRef, @@ -34,6 +35,13 @@ export class NativeInput { _change(ev: any) { this.valueChange.emit(ev.target.value); } + + @HostListener('keydown', ['$event']) + _keyDown(ev: any) { + if(ev) { + ev.target && this.keydown.emit(ev.target.value); + } + } @HostListener('focus') _focus() { diff --git a/src/components/input/test/clear-after-edit/app-module.ts b/src/components/input/test/clear-after-edit/app-module.ts new file mode 100644 index 00000000000..4ca5dbb6bf3 --- /dev/null +++ b/src/components/input/test/clear-after-edit/app-module.ts @@ -0,0 +1,33 @@ +import { Component, NgModule } from '@angular/core'; +import { IonicApp, IonicModule } from '../../../..'; + + +@Component({ + templateUrl: 'main.html' +}) +export class E2EPage { + myValue = ''; + myValue2 = ''; +} + +@Component({ + template: '' +}) +export class E2EApp { + rootPage = E2EPage; +} + +@NgModule({ + declarations: [ + E2EApp, + E2EPage + ], + imports: [ + IonicModule.forRoot(E2EApp) + ], + bootstrap: [IonicApp], + entryComponents: [ + E2EPage + ] +}) +export class AppModule {} diff --git a/src/components/input/test/clear-after-edit/e2e.ts b/src/components/input/test/clear-after-edit/e2e.ts new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/components/input/test/clear-after-edit/main.html b/src/components/input/test/clear-after-edit/main.html new file mode 100644 index 00000000000..ecc0c7d774e --- /dev/null +++ b/src/components/input/test/clear-after-edit/main.html @@ -0,0 +1,24 @@ + + + + Clear After Edit + + + + + + + + + + + Email + + + + Password + + + + +