-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathtouch-input-nav.js
More file actions
111 lines (96 loc) · 3.38 KB
/
touch-input-nav.js
File metadata and controls
111 lines (96 loc) · 3.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/*
* touch-input-nav.js
* https://github.com/ChrisWren/touch-input-nav
*
* Copyright (c) 2013 Chris Wren & contributors
* Licensed under the MIT license.
*/
/* jshint -W015 */
;(function () {
'use strict';
// Negates the user agent :disabled input field styling on a per os/browser basis
var osData = {
iOSSafari: {
touchEvent: 'touchstart',
styles: {
input: {
'opacity': 1
},
textarea: {
'opacity': 1
},
select: {
'color': 'black'
}
}
}
// Add more browser/OS combos here
};
// List of known mobile OS and browser combos which have tabable input navigation
function getTabableOsAndBrowser() {
if (window.navigator.userAgent.match(/iPhone|iPad|iPod/)) {
return 'iOSSafari';
}
// Add more browser/OS combos here
}
/**
* Public method which sets up form-scoped touch input navigation
* @param {String} className Custom class to override for custom styling
* @return {Boolean} Returns false if current browser doesn't have tabable input navigation
*/
var touchInputNav = function (className) {
var tabableOsAndBrowser = getTabableOsAndBrowser();
if (!tabableOsAndBrowser) {
return false;
}
// Allow user to use a custom className so that they can do specific styling
// per browser/os combo if they so desire
var disabledClassName = className || 'input-disabled';
// Generate a <style> tag to insert into the page instead of assigning inline-styles
var styleString = '';
for (var element in osData[tabableOsAndBrowser].styles) {
styleString += element + ':disabled.' + disabledClassName + '{';
for (var key in osData[tabableOsAndBrowser].styles[element]) {
styleString += key + ':' + osData[tabableOsAndBrowser].styles[element][key] + ';';
}
styleString += '}';
}
$('<style>', {
id: 'touch-input-nav-styles'
}).html(styleString).appendTo('head');
var inputSelectorString = 'input,select,textarea';
$(document).on('focus', inputSelectorString, function () {
var $this = $(this);
var $formInputs = $this.closest('form').find(inputSelectorString);
var $otherInputs = $(inputSelectorString).not($formInputs);
// Disable inputs that are outside of the current <form> scope
$otherInputs
.prop('disabled', true)
.addClass(disabledClassName + ' ' + tabableOsAndBrowser);
// When the currently focused input element blurs, un-disable all the others
$this.one('blur', function () {
$(inputSelectorString).off('.input-disabled');
$otherInputs
.prop('disabled', false)
.removeClass(disabledClassName + ' ' + tabableOsAndBrowser);
});
// If a disabled input field is tapped allow it to be focused
// by removing the disabled attribute
$(inputSelectorString).one(osData[tabableOsAndBrowser].touchEvent + '.input-disabled', function () {
$(this).prop('disabled', false);
});
});
};
if (typeof define === 'function' && typeof define.amd === 'object' && define.amd) {
define(['jquery'], function () {
return touchInputNav;
});
} else {
if (typeof module === 'object' && module.exports) {
require('jquery')(window);
module.exports = touchInputNav;
} else {
window.touchInputNav = touchInputNav;
}
}
})();