Skip to content

Commit b53d707

Browse files
committed
feat(input): default autocomplete/autocorrect=off, fix autofocus
Related: #5480
1 parent 1cfca53 commit b53d707

File tree

9 files changed

+228
-102
lines changed

9 files changed

+228
-102
lines changed

ionic/components/input/input-base.ts

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ export class InputBase {
2424
protected _useAssist: boolean = true;
2525
protected _value = '';
2626
protected _isTouch: boolean;
27+
protected _autoFocusAssist: string;
28+
protected _autoComplete: string;
29+
protected _autoCorrect: string;
2730

2831
inputControl: NgControl;
2932

@@ -45,6 +48,10 @@ export class InputBase {
4548
this._useAssist = config.get('scrollAssist');
4649
this._keyboardHeight = config.get('keyboardHeight');
4750

51+
this._autoFocusAssist = config.get('autoFocusAssist', 'delay');
52+
this._autoComplete = config.get('autocomplete', 'off');
53+
this._autoCorrect = config.get('autocorrect', 'off');
54+
4855
if (ngControl) {
4956
ngControl.valueAccessor = this;
5057
}
@@ -176,8 +183,44 @@ export class InputBase {
176183
this.checkHasValue(nativeInput.getValue());
177184
this.disabled = this._disabled;
178185

186+
var ionInputEle: HTMLElement = this._elementRef.nativeElement;
187+
let nativeInputEle: HTMLElement = nativeInput.element();
188+
179189
// copy ion-input attributes to the native input element
180-
copyInputAttributes(this._elementRef.nativeElement, nativeInput.element());
190+
copyInputAttributes(ionInputEle, nativeInputEle);
191+
192+
if (ionInputEle.hasAttribute('autofocus')) {
193+
// the ion-input element has the autofocus attributes
194+
ionInputEle.removeAttribute('autofocus');
195+
196+
if (this._autoFocusAssist === 'immediate') {
197+
// config says to immediate focus on the input
198+
// works best on android devices
199+
nativeInputEle.focus();
200+
201+
} else if (this._autoFocusAssist === 'delay') {
202+
// config says to chill out a bit and focus on the input after transitions
203+
// works best on desktop
204+
setTimeout(() => {
205+
nativeInputEle.focus();
206+
}, 650);
207+
}
208+
209+
// traditionally iOS has big issues with autofocus on actual devices
210+
// autoFocus is disabled by default with the iOS mode config
211+
}
212+
213+
// by default set autocomplete="off" unless specified by the input
214+
if (ionInputEle.hasAttribute('autocomplete')) {
215+
this._autoComplete = ionInputEle.getAttribute('autocomplete');
216+
}
217+
nativeInputEle.setAttribute('autocomplete', this._autoComplete);
218+
219+
// by default set autocomplete="off" unless specified by the input
220+
if (ionInputEle.hasAttribute('autocorrect')) {
221+
this._autoCorrect = ionInputEle.getAttribute('autocorrect');
222+
}
223+
nativeInputEle.setAttribute('autocorrect', this._autoCorrect);
181224
}
182225

183226
/**

ionic/components/modal/test/basic/index.ts

Lines changed: 74 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ import {Modal, ActionSheet, NavController, NavParams, Transition, TransitionOpti
66
templateUrl: 'main.html'
77
})
88
class E2EPage {
9+
platforms;
910

10-
constructor(nav: NavController, config: Config, platform: Platform) {
11-
this.nav = nav;
11+
constructor(private nav: NavController, config: Config, platform: Platform) {
1212
console.log('platforms', platform.platforms());
1313
console.log('mode', config.get('mode'));
1414

@@ -55,6 +55,14 @@ class E2EPage {
5555
});
5656
}
5757

58+
presentModalWithInputs() {
59+
let modal = Modal.create(ModalWithInputs);
60+
modal.onDismiss((data) => {
61+
console.log('Modal with inputs data:', data);
62+
});
63+
this.nav.present(modal);
64+
}
65+
5866
presentModalCustomAnimation() {
5967
let modal = Modal.create(ContactUs);
6068
this.nav.present(modal, {
@@ -85,12 +93,13 @@ class E2EPage {
8593
`
8694
})
8795
class ModalPassData {
88-
constructor(params: NavParams, viewCtrl: ViewController) {
96+
data;
97+
98+
constructor(params: NavParams, private viewCtrl: ViewController) {
8999
this.data = {
90100
userId: params.get('userId'),
91101
name: 'Jenny'
92102
};
93-
this.viewCtrl = viewCtrl;
94103
}
95104

96105
submit() {
@@ -118,9 +127,7 @@ class ModalPassData {
118127
})
119128
class ToolbarModal {
120129

121-
constructor(viewCtrl: ViewController) {
122-
this.viewCtrl = viewCtrl;
123-
}
130+
constructor(private viewCtrl: ViewController) {}
124131

125132
dismiss() {
126133
this.viewCtrl.emit({
@@ -133,12 +140,66 @@ class ToolbarModal {
133140

134141

135142
@Page({
136-
template: '<ion-nav [root]="rootView"></ion-nav>'
143+
template: `
144+
<ion-toolbar secondary>
145+
<ion-buttons start>
146+
<button (click)="dismiss()">Close</button>
147+
</ion-buttons>
148+
<ion-title>Modal w/ Inputs</ion-title>
149+
</ion-toolbar>
150+
<ion-content>
151+
<form #addForm="ngForm" (submit)="save($event)" novalidate>
152+
<ion-list>
153+
<ion-item>
154+
<ion-label floating>Title <span [hidden]="title.valid">(Required)</span></ion-label>
155+
<ion-input ngControl="title" type="text" [(ngModel)]="data.title" #title="ngForm" required autofocus></ion-input>
156+
</ion-item>
157+
<ion-item>
158+
<ion-label floating>Note <span [hidden]="note.valid">(Required)</span></ion-label>
159+
<ion-input ngControl="note" type="text" [(ngModel)]="data.note" #note="ngForm" required></ion-input>
160+
</ion-item>
161+
<ion-item>
162+
<ion-label floating>Icon</ion-label>
163+
<ion-input ngControl="icon" type="text" [(ngModel)]="data.icon" #icon="ngForm" autocomplete="on" autocorrect="on"></ion-input>
164+
</ion-item>
165+
</ion-list>
166+
<div padding>
167+
<button block large type="submit" [disabled]="!addForm.valid">Save</button>
168+
</div>
169+
</form>
170+
</ion-content>
171+
`
172+
})
173+
class ModalWithInputs {
174+
data;
175+
176+
constructor(private viewCtrl: ViewController) {
177+
this.data = {
178+
title: 'Title',
179+
note: 'Note',
180+
icon: 'home'
181+
};
182+
}
183+
184+
public save(ev) {
185+
this.viewCtrl.dismiss(this.data);
186+
}
187+
188+
public dismiss() {
189+
this.viewCtrl.dismiss(null);
190+
}
191+
}
192+
193+
194+
@Page({
195+
template: '<ion-nav [root]="root"></ion-nav>'
137196
})
138197
class ContactUs {
198+
root;
199+
139200
constructor() {
140201
console.log('ContactUs constructor');
141-
this.rootView = ModalFirstPage;
202+
this.root = ModalFirstPage;
142203
}
143204
onPageLoaded() {
144205
console.log('ContactUs onPageLoaded');
@@ -185,9 +246,7 @@ class ContactUs {
185246
`
186247
})
187248
class ModalFirstPage {
188-
constructor(nav: NavController) {
189-
this.nav = nav;
190-
}
249+
constructor(private nav: NavController) {}
191250

192251
push() {
193252
let page = ModalSecondPage;
@@ -265,10 +324,9 @@ class ModalFirstPage {
265324
})
266325
class ModalSecondPage {
267326
constructor(
268-
nav: NavController,
327+
private nav: NavController,
269328
params: NavParams
270329
) {
271-
this.nav = nav;
272330
console.log('Second page params:', params);
273331
}
274332
}
@@ -278,6 +336,8 @@ class ModalSecondPage {
278336
template: '<ion-nav [root]="root"></ion-nav>'
279337
})
280338
class E2EApp {
339+
root;
340+
281341
constructor() {
282342
this.root = E2EPage;
283343
}

ionic/components/modal/test/basic/main.html

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
<p>
1414
<button class="e2eOpenToolbarModal" (click)="presentToolbarModal()">Present modal w/ toolbar</button>
1515
</p>
16+
<p>
17+
<button (click)="presentModalWithInputs()">Present modal w/ inputs</button>
18+
</p>
1619
<p>
1720
<button (click)="presentModalCustomAnimation()">Modal: Custom Animation</button>
1821
</p>

0 commit comments

Comments
 (0)