Skip to content

Commit 4636cb0

Browse files
committed
fix(keyboard): shrink scrollView on date and select focus on iOS
1 parent f71c04d commit 4636cb0

File tree

3 files changed

+74
-6
lines changed

3 files changed

+74
-6
lines changed

Diff for: js/utils/keyboard.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,9 @@ function keyboardNativeShow(e) {
143143
}
144144

145145
function keyboardBrowserFocusIn(e) {
146-
if( !e.target || e.target.readOnly || !ionic.tap.isTextInput(e.target) || ionic.tap.isDateInput(e.target) || !keyboardIsWithinScroll(e.target) ) return;
146+
if( !e.target || e.target.readOnly || !ionic.tap.isKeyboardElement(e.target) || !keyboardIsWithinScroll(e.target) ) return;
147147

148+
console.log("keyboardBrowserFocusIn");
148149
document.addEventListener('keydown', keyboardOnKeyDown, false);
149150

150151
document.body.scrollTop = 0;

Diff for: js/utils/tap.js

+13-5
Original file line numberDiff line numberDiff line change
@@ -162,14 +162,22 @@ ionic.tap = {
162162
return !!ele &&
163163
(ele.tagName == 'TEXTAREA' ||
164164
ele.contentEditable === 'true' ||
165-
(ele.tagName == 'INPUT' && !(/^(radio|checkbox|range|file|submit|reset)$/i).test(ele.type)));
165+
(ele.tagName == 'INPUT' && !(/^(radio|checkbox|range|file|submit|reset|color|image|button)$/i).test(ele.type)));
166166
},
167167

168168
isDateInput: function(ele) {
169169
return !!ele &&
170170
(ele.tagName == 'INPUT' && (/^(date|time|datetime-local|month|week)$/i).test(ele.type));
171171
},
172172

173+
isKeyboardElement: function(ele) {
174+
if ( !ionic.Platform.isIOS() ) {
175+
return ionic.tap.isTextInput(ele) && !ionic.tap.isDateInput(ele);
176+
} else {
177+
return ionic.tap.isTextInput(ele) || ( !!ele && ele.tagName == "SELECT");
178+
}
179+
},
180+
173181
isLabelWithTextInput: function(ele) {
174182
var container = tapContainingElement(ele, false);
175183

@@ -181,15 +189,15 @@ ionic.tap = {
181189
return ionic.tap.isTextInput(ele) || ionic.tap.isLabelWithTextInput(ele);
182190
},
183191

184-
cloneFocusedInput: function(container, scrollIntance) {
192+
cloneFocusedInput: function(container) {
185193
if (ionic.tap.hasCheckedClone) return;
186194
ionic.tap.hasCheckedClone = true;
187195

188196
ionic.requestAnimationFrame(function() {
189197
var focusInput = container.querySelector(':focus');
190198
if (ionic.tap.isTextInput(focusInput)) {
191199
var clonedInput = focusInput.cloneNode(true);
192-
200+
193201
clonedInput.value = focusInput.value;
194202
clonedInput.classList.add('cloned-text-input');
195203
clonedInput.readOnly = true;
@@ -207,7 +215,7 @@ ionic.tap = {
207215

208216
hasCheckedClone: false,
209217

210-
removeClonedInputs: function(container, scrollIntance) {
218+
removeClonedInputs: function(container) {
211219
ionic.tap.hasCheckedClone = false;
212220

213221
ionic.requestAnimationFrame(function() {
@@ -509,7 +517,7 @@ function tapFocusOutActive() {
509517

510518
function tapFocusIn(e) {
511519
// Because a text input doesn't preventDefault (so the caret still works) there's a chance
512-
// that it's mousedown event 300ms later will change the focus to another element after
520+
// that its mousedown event 300ms later will change the focus to another element after
513521
// the keyboard shows up.
514522

515523
if (tapEnabledTouchEvents &&

Diff for: test/unit/utils/tap.unit.js

+59
Original file line numberDiff line numberDiff line change
@@ -1215,6 +1215,15 @@ describe('Ionic Tap', function() {
12151215
ele.type = 'checkbox';
12161216
expect( ionic.tap.isTextInput(ele) ).toEqual(false);
12171217

1218+
ele.type = 'color';
1219+
expect( ionic.tap.isTextInput(ele) ).toEqual(false);
1220+
1221+
ele.type = 'button';
1222+
expect( ionic.tap.isTextInput(ele) ).toEqual(false);
1223+
1224+
ele.type = 'image';
1225+
expect( ionic.tap.isTextInput(ele) ).toEqual(false);
1226+
12181227
ele = document.createElement('select');
12191228
expect( ionic.tap.isTextInput(ele) ).toEqual(false);
12201229

@@ -1255,7 +1264,57 @@ describe('Ionic Tap', function() {
12551264

12561265
ele.type = 'text';
12571266
expect( ionic.tap.isDateInput(ele) ).toEqual(false);
1267+
});
1268+
1269+
it('Should isKeyboardElement on date and select on iOS', function() {
1270+
expect( ionic.tap.isKeyboardElement(null) ).toEqual(false);
1271+
1272+
ionic.Platform.setPlatform('ios');
1273+
1274+
var ele = document.createElement('input');
1275+
ele.type = 'date';
1276+
expect( ionic.tap.isKeyboardElement(ele) ).toEqual(true);
1277+
1278+
ele.type = 'datetime-local';
1279+
expect( ionic.tap.isKeyboardElement(ele) ).toEqual(true);
1280+
1281+
ele.type = 'month';
1282+
expect( ionic.tap.isKeyboardElement(ele) ).toEqual(true);
1283+
1284+
ele.type = 'week';
1285+
expect( ionic.tap.isKeyboardElement(ele) ).toEqual(true);
1286+
1287+
ele.type = 'time';
1288+
expect( ionic.tap.isKeyboardElement(ele) ).toEqual(true);
1289+
1290+
ele = document.createElement('select');
1291+
expect ( ionic.tap.isKeyboardElement(ele)).toEqual(true);
1292+
1293+
});
1294+
1295+
it('Should not isKeyboardElement on date and select on Android', function() {
1296+
expect( ionic.tap.isKeyboardElement(null) ).toEqual(false);
1297+
1298+
ionic.Platform.setPlatform('android');
1299+
1300+
var ele = document.createElement('input');
1301+
ele.type = 'date';
1302+
expect( ionic.tap.isKeyboardElement(ele) ).toEqual(false);
1303+
1304+
ele.type = 'datetime-local';
1305+
expect( ionic.tap.isKeyboardElement(ele) ).toEqual(false);
1306+
1307+
ele.type = 'month';
1308+
expect( ionic.tap.isKeyboardElement(ele) ).toEqual(false);
12581309

1310+
ele.type = 'week';
1311+
expect( ionic.tap.isKeyboardElement(ele) ).toEqual(false);
1312+
1313+
ele.type = 'time';
1314+
expect( ionic.tap.isKeyboardElement(ele) ).toEqual(false);
1315+
1316+
ele = document.createElement('select');
1317+
expect ( ionic.tap.isKeyboardElement(ele)).toEqual(false);
12591318
});
12601319

12611320
it('Should isLabelWithTextInput', function() {

0 commit comments

Comments
 (0)