mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-21 21:15:24 +08:00
feat(input): clearOnEdit feature. Closes #9187
This commit is contained in:
@ -32,6 +32,11 @@ export class InputBase extends Ion {
|
|||||||
_nav: NavControllerBase;
|
_nav: NavControllerBase;
|
||||||
_native: NativeInput;
|
_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;
|
inputControl: NgControl;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@ -133,6 +138,33 @@ export class InputBase extends Ion {
|
|||||||
this._native && this._native.isDisabled(this._disabled);
|
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
|
* @private
|
||||||
*/
|
*/
|
||||||
@ -147,6 +179,10 @@ export class InputBase extends Ion {
|
|||||||
this.onChange(inputValue);
|
this.onChange(inputValue);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
nativeInput.keydown.subscribe((inputValue: any) => {
|
||||||
|
this.onKeydown(inputValue);
|
||||||
|
});
|
||||||
|
|
||||||
this.focusChange(this.hasFocus());
|
this.focusChange(this.hasFocus());
|
||||||
nativeInput.focusChange.subscribe((textInputHasFocus: any) => {
|
nativeInput.focusChange.subscribe((textInputHasFocus: any) => {
|
||||||
this.focusChange(textInputHasFocus);
|
this.focusChange(textInputHasFocus);
|
||||||
@ -228,6 +264,16 @@ export class InputBase extends Ion {
|
|||||||
this.checkHasValue(val);
|
this.checkHasValue(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* onKeydown handler for clearOnEdit
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
onKeydown(val: any) {
|
||||||
|
if(this._clearOnEdit) {
|
||||||
|
this.checkClearOnEdit(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
@ -241,12 +287,21 @@ export class InputBase extends Ion {
|
|||||||
return this._native.hasFocus();
|
return this._native.hasFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
hasValue(): boolean {
|
||||||
|
let inputValue = this._value;
|
||||||
|
return (inputValue !== null && inputValue !== undefined && inputValue !== '');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
checkHasValue(inputValue: any) {
|
checkHasValue(inputValue: any) {
|
||||||
if (this._item) {
|
if (this._item) {
|
||||||
let hasValue = (inputValue !== null && inputValue !== undefined && inputValue !== '');
|
let hasValue = (inputValue !== null && inputValue !== undefined && inputValue !== '');
|
||||||
|
|
||||||
this._item.setElementClass('input-has-value', hasValue);
|
this._item.setElementClass('input-has-value', hasValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -260,6 +315,12 @@ export class InputBase extends Ion {
|
|||||||
}
|
}
|
||||||
if (!inputHasFocus) {
|
if (!inputHasFocus) {
|
||||||
this.deregScrollMove();
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,6 +160,18 @@ export class TextInput extends InputBase {
|
|||||||
this._setMode(val);
|
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
|
* @private
|
||||||
*/
|
*/
|
||||||
@ -207,6 +219,11 @@ export class TextInput extends InputBase {
|
|||||||
this._item.setElementClass('item-input', true);
|
this._item.setElementClass('item-input', true);
|
||||||
this._item.registerInput(this._type);
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -19,6 +19,7 @@ export class NativeInput {
|
|||||||
|
|
||||||
@Output() focusChange: EventEmitter<boolean> = new EventEmitter<boolean>();
|
@Output() focusChange: EventEmitter<boolean> = new EventEmitter<boolean>();
|
||||||
@Output() valueChange: EventEmitter<string> = new EventEmitter<string>();
|
@Output() valueChange: EventEmitter<string> = new EventEmitter<string>();
|
||||||
|
@Output() keydown: EventEmitter<string> = new EventEmitter<string>();
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public _elementRef: ElementRef,
|
public _elementRef: ElementRef,
|
||||||
@ -34,6 +35,13 @@ export class NativeInput {
|
|||||||
_change(ev: any) {
|
_change(ev: any) {
|
||||||
this.valueChange.emit(ev.target.value);
|
this.valueChange.emit(ev.target.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@HostListener('keydown', ['$event'])
|
||||||
|
_keyDown(ev: any) {
|
||||||
|
if(ev) {
|
||||||
|
ev.target && this.keydown.emit(ev.target.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@HostListener('focus')
|
@HostListener('focus')
|
||||||
_focus() {
|
_focus() {
|
||||||
|
33
src/components/input/test/clear-after-edit/app-module.ts
Normal file
33
src/components/input/test/clear-after-edit/app-module.ts
Normal file
@ -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: '<ion-nav [root]="rootPage"></ion-nav>'
|
||||||
|
})
|
||||||
|
export class E2EApp {
|
||||||
|
rootPage = E2EPage;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
declarations: [
|
||||||
|
E2EApp,
|
||||||
|
E2EPage
|
||||||
|
],
|
||||||
|
imports: [
|
||||||
|
IonicModule.forRoot(E2EApp)
|
||||||
|
],
|
||||||
|
bootstrap: [IonicApp],
|
||||||
|
entryComponents: [
|
||||||
|
E2EPage
|
||||||
|
]
|
||||||
|
})
|
||||||
|
export class AppModule {}
|
0
src/components/input/test/clear-after-edit/e2e.ts
Normal file
0
src/components/input/test/clear-after-edit/e2e.ts
Normal file
24
src/components/input/test/clear-after-edit/main.html
Normal file
24
src/components/input/test/clear-after-edit/main.html
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<ion-header>
|
||||||
|
|
||||||
|
<ion-toolbar>
|
||||||
|
<ion-title>Clear After Edit</ion-title>
|
||||||
|
</ion-toolbar>
|
||||||
|
|
||||||
|
</ion-header>
|
||||||
|
|
||||||
|
|
||||||
|
<ion-content>
|
||||||
|
|
||||||
|
<ion-list>
|
||||||
|
|
||||||
|
<ion-item>
|
||||||
|
<ion-label>Email</ion-label>
|
||||||
|
<ion-input class="e2eClearInput" [(ngModel)]="myValue2" type="email"></ion-input>
|
||||||
|
</ion-item>
|
||||||
|
<ion-item>
|
||||||
|
<ion-label>Password</ion-label>
|
||||||
|
<ion-input class="e2eClearInput" [(ngModel)]="myValue" type="password"></ion-input>
|
||||||
|
</ion-item>
|
||||||
|
</ion-list>
|
||||||
|
|
||||||
|
</ion-content>
|
Reference in New Issue
Block a user