Commit f367ed65607e716a5d876429afedfe762a212d00
Exists in
master
and in
1 other branch
Merge branch 'master' into 'master'
Master (pmarco) See merge request modulos-npm/foca-teclado!2
Showing
4 changed files
Show diff stats
gulpfile.js
src/js/angular-on-screen-keyboard-directive.js
... | ... | @@ -0,0 +1,199 @@ |
1 | +angular.module('onScreenKeyboard', ['ngSanitize']) | |
2 | + .directive('onScreenKeyboard', ['$timeout', '$document', function($timeout, $document) { | |
3 | + return { | |
4 | + restrict: 'E', | |
5 | + bindToController: true, | |
6 | + controllerAs: 'ctrl', | |
7 | + scope: { | |
8 | + rows : '=?', | |
9 | + uppercaseAllWords : '@', | |
10 | + alfanumeric : '=?', | |
11 | + numeric : '=?' | |
12 | + }, | |
13 | + controller: ['$sce', '$scope', function($sce, $scope) { | |
14 | + var ctrl = this; | |
15 | + | |
16 | + if (!ctrl.rows) { | |
17 | + ctrl.rows = [ | |
18 | + ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', { | |
19 | + type: 'erase', colspan: 2, text: '⇐' | |
20 | + }], | |
21 | + ['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '@'], | |
22 | + ['a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', '-', '_', {type: 'margin'}], | |
23 | + [ | |
24 | + {type: 'shift', upperCase: '⇓', lowerCase: '⇑'}, | |
25 | + 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', | |
26 | + {type: 'shift', upperCase: '⇓', lowerCase: '⇑'} | |
27 | + ], | |
28 | + [{type: 'margin'}, {type: 'space', colspan: 9, text: ' '}] | |
29 | + ]; | |
30 | + } | |
31 | + | |
32 | + ctrl.getText = function(key) { | |
33 | + if (key.type === 'margin') { | |
34 | + return ''; | |
35 | + } | |
36 | + | |
37 | + var val = ''; | |
38 | + | |
39 | + if (key.text) { | |
40 | + val = key.text; | |
41 | + } | |
42 | + else if (key.lowerCase && !ctrl.isUpperCase) { | |
43 | + val = key.lowerCase; | |
44 | + } | |
45 | + else if (key.upperCase && ctrl.isUpperCase) { | |
46 | + val = key.upperCase; | |
47 | + } | |
48 | + else { | |
49 | + val = ctrl.isUpperCase ? key.toUpperCase() : key.toLowerCase(); | |
50 | + } | |
51 | + | |
52 | + if (val && val.indexOf('&') > -1) { | |
53 | + return $sce.trustAsHtml(val); | |
54 | + } | |
55 | + | |
56 | + return val; | |
57 | + }; | |
58 | + $scope.fondo = function() { | |
59 | + $timeout(function() { | |
60 | + ctrl.lastInputCtrl.focus(); | |
61 | + $scope.$emit('focus'); | |
62 | + }); | |
63 | + }; | |
64 | + }], | |
65 | + link: function(scope, element, attr) { | |
66 | + var ctrl = scope.ctrl; | |
67 | + ctrl.isUpperCase = false; | |
68 | + ctrl.lastInputCtrl = null; | |
69 | + ctrl.startPos = null; | |
70 | + ctrl.endPos = null; | |
71 | + | |
72 | + ctrl.printKeyStroke = function(key, event) { | |
73 | + | |
74 | + if (!ctrl.lastInputCtrl) { | |
75 | + return; | |
76 | + } | |
77 | + | |
78 | + ctrl.startPos = ctrl.lastInputCtrl.selectionStart; | |
79 | + ctrl.endPos = ctrl.lastInputCtrl.selectionEnd; | |
80 | + | |
81 | + if (key.type === 'erase') { | |
82 | + ctrl.eraseKeyStroke(); | |
83 | + return; | |
84 | + } else if (key.type === 'shift') { | |
85 | + ctrl.isUpperCase = !ctrl.isUpperCase; | |
86 | + return; | |
87 | + } | |
88 | + | |
89 | + var htmlKeyVal = angular.element(event.target || event.srcElement).text(); | |
90 | + var lastInputCtrl = angular.element(ctrl.lastInputCtrl); | |
91 | + var val = lastInputCtrl.val(); | |
92 | + var pre = val.substring(0, ctrl.startPos); | |
93 | + var post = val.substring(ctrl.endPos, val.length); | |
94 | + lastInputCtrl.val(pre + htmlKeyVal + post); | |
95 | + lastInputCtrl.triggerHandler('change'); | |
96 | + | |
97 | + ctrl.startPos += htmlKeyVal.length; | |
98 | + ctrl.endPos += htmlKeyVal.length; | |
99 | + ctrl.lastInputCtrl.selectionStart = ctrl.startPos; | |
100 | + ctrl.lastInputCtrl.selectionEnd = ctrl.startPos; | |
101 | + ctrl.setKeyboardLayout(); | |
102 | + ctrl.refocus(); | |
103 | + }; | |
104 | + | |
105 | + ctrl.refocus = function() { | |
106 | + ctrl.lastInputCtrl.focus(); | |
107 | + }; | |
108 | + | |
109 | + ctrl.eraseKeyStroke = function() { | |
110 | + if (!ctrl.lastInputCtrl) { | |
111 | + return; | |
112 | + } | |
113 | + | |
114 | + var hasSel = ctrl.startPos !== ctrl.endPos; | |
115 | + | |
116 | + var lastInputCtrl = angular.element(ctrl.lastInputCtrl); | |
117 | + var val = lastInputCtrl.val(); | |
118 | + var pre = val.substring(0, hasSel ? ctrl.startPos : ctrl.startPos - 1); | |
119 | + var post = val.substring(ctrl.endPos, val.length); | |
120 | + | |
121 | + lastInputCtrl.val(pre + post); | |
122 | + lastInputCtrl.triggerHandler('change'); | |
123 | + | |
124 | + if (hasSel) { | |
125 | + ctrl.endPos = ctrl.startPos; | |
126 | + } | |
127 | + else { | |
128 | + ctrl.startPos--; | |
129 | + ctrl.endPos--; | |
130 | + } | |
131 | + ctrl.lastInputCtrl.selectionStart = ctrl.startPos; | |
132 | + ctrl.lastInputCtrl.selectionEnd = ctrl.startPos; | |
133 | + ctrl.setKeyboardLayout(); | |
134 | + ctrl.refocus(); | |
135 | + }; | |
136 | + | |
137 | + ctrl.setKeyboardLayout = function() { | |
138 | + if (!ctrl.lastInputCtrl) { | |
139 | + ctrl.isUpperCase = true; | |
140 | + return; | |
141 | + } | |
142 | + else if (ctrl.lastInputCtrl.className && ctrl.isUpperCase) { | |
143 | + ctrl.isUpperCase = true; | |
144 | + } | |
145 | + else if (angular.element(ctrl.lastInputCtrl).val().length === 0) { | |
146 | + ctrl.isUpperCase = true; | |
147 | + } | |
148 | + else if ( | |
149 | + angular.element(ctrl.lastInputCtrl).val().slice(-1) === ' ' && | |
150 | + !ctrl.isUpperCase && attr.uppercaseAllWords !== undefined | |
151 | + ) { | |
152 | + ctrl.isUpperCase = true; | |
153 | + } | |
154 | + else{ | |
155 | + ctrl.isUpperCase = true; | |
156 | + } | |
157 | + }; | |
158 | + | |
159 | + var focusin = function(event) { | |
160 | + var e = event.target || event.srcElement; | |
161 | + | |
162 | + if (e.tagName === 'INPUT' || e.tagName === 'TEXTAREA') { | |
163 | + ctrl.lastInputCtrl = e; | |
164 | + ctrl.setKeyboardLayout(); | |
165 | + } | |
166 | + }; | |
167 | + | |
168 | + var keyup = function() { | |
169 | + if (!ctrl.lastInputCtrl) { | |
170 | + return; | |
171 | + } | |
172 | + | |
173 | + ctrl.startPos = ctrl.lastInputCtrl.selectionStart; | |
174 | + ctrl.endPos = ctrl.lastInputCtrl.selectionEnd; | |
175 | + | |
176 | + ctrl.setKeyboardLayout(); | |
177 | + scope.$digest(); | |
178 | + }; | |
179 | + | |
180 | + $document.bind('focusin', focusin); | |
181 | + $document.bind('keyup', keyup); | |
182 | + | |
183 | + scope.$on("$destroy", function() { | |
184 | + $document.unbind('focusin', focusin); | |
185 | + $document.unbind('keyup', keyup); | |
186 | + }); | |
187 | + | |
188 | + element.bind('contextmenu', function(event) { | |
189 | + event.preventDefault(); | |
190 | + return false; | |
191 | + }); | |
192 | + | |
193 | + $timeout(function() { | |
194 | + ctrl.isUpperCase = true; | |
195 | + }, 0); | |
196 | + }, | |
197 | + templateUrl: 'src/views/angular-on-screen-keyboard.html' | |
198 | + }; | |
199 | + }]); |
src/views/angular-on-screen-keyboard.html
... | ... | @@ -0,0 +1,38 @@ |
1 | +<div class="keyboard" ng-mousedown="fondo()"> | |
2 | + <div class="row"> | |
3 | + <table | |
4 | + class="form-group col-12 col-sm-6 col-md-9" | |
5 | + ng-show="ctrl.alfanumeric" | |
6 | + > | |
7 | + <tr ng-repeat="row in ctrl.rows.alfa"> | |
8 | + <td ng-repeat="key in row" | |
9 | + ng-click="ctrl.printKeyStroke(key, $event)" | |
10 | + colspan="{{key.colspan || 1}}" | |
11 | + ng-class="{ | |
12 | + 'number': key.type === 'number', 'letter': key.type !== 'margin' && | |
13 | + key.type !== 'number' | |
14 | + }" | |
15 | + ng-bind-html="ctrl.getText(key)" | |
16 | + > | |
17 | + </td> | |
18 | + </tr> | |
19 | + </table> | |
20 | + <table | |
21 | + class="form-group col-12 col-sm-6 col-md-3" | |
22 | + ng-show="ctrl.numeric" | |
23 | + > | |
24 | + <tr ng-repeat="row in ctrl.rows.numeric"> | |
25 | + <td ng-repeat="key in row" | |
26 | + ng-click="ctrl.printKeyStroke(key, $event)" | |
27 | + colspan="{{key.colspan || 1}}" | |
28 | + ng-class="{ | |
29 | + 'number': key.type === 'number', 'letter': key.type !== 'margin' && | |
30 | + key.type !== 'number' | |
31 | + }" | |
32 | + ng-bind-html="ctrl.getText(key)" | |
33 | + > | |
34 | + </td> | |
35 | + </tr> | |
36 | + </table> | |
37 | + </div> | |
38 | +</div> |