JSFiddle - React, Tailwind, and code Playground
HTML
<div ng-app="yourApp" ng-controller="loginFormCtrl">
<kbd-widget>
<input type="text" ng-model="data.login" />
<input type="password" ng-model="data.password" />
</kbd-widget>
</div>
JavaScript
angular.module('yourApp', []).
controller('loginFormCtrl', ['$scope', function ($scope) {
$scope.data = {
login: 'hey',
password: ''
};
}]).
// Widget encompassing virtual-keyboard-enabled inputs
directive('kbdWidget', function () {
return {
restrict: 'E',
transclude: true,
template: '<div ng-transclude></div>' +
'<kbd ng-show="activeInput"></kbd>',
controller: ['$scope', function ($scope) {
$scope.activeInput = null;
var focusInput = function () {
$scope.activeInput && $scope.activeInput.focus();
};
this.applyToActiveInput = function (func) {
if ($scope.activeInput) {
setTimeout(focusInput, 5);
func($scope.activeInput);
}
};
this.focusInput = focusInput;
}],
link: function (scope, element, attr) {
element.find('input').bind('focus', function (evt) {
scope.$apply(function () {
scope.activeInput = evt.target;
});
});
}
}
}).
// Virtual keyboard
directive('kbd', ['kbdButtons', function (buttons) {
return {
restrict: 'E',
require: '^kbdWidget',
link: function (scope, element, attr, widgetCtrl) {
angular.forEach(buttons, function (btn) {
var el = angular.element(
'<button>' + btn.label + '</button>');
var repeatAction = function () {
widgetCtrl.applyToActiveInput(btn.action);
btn.timeout = setTimeout(repeatAction, 250);
};
el.bind('mousedown', function () {
repeatAction();
});
el.bind('mouseup', function () {
clearTimeout(btn.timeout);
...