在AngularJS表键盘导航 [英] Keyboard navigation in AngularJS table
问题描述
我想端口在Windows(Delphi的VCL)作出一个角度应用一个特殊的表/网格的形式。
角应用的一个简化版可以在这里进行测试:的jsfiddle演示
他想,作为证明的jsfiddle用户可以添加任意多行。
现在的问题是:是否有可能解决与角指令或某些其他角魔以下
?- 跳转到下一个单元(单元向右或新行)回车键时为pressed。
- 跳转到小区正下方的向下箭头。
- 跳转到电池正上方的箭头了。
HTML
<&TBODY GT;
< TR NG重复=P人员>
&所述; TD>
<输入NG模型=p.name>
< / TD>
&所述; TD>
<输入NG模型=p.age>
< / TD>
&所述; TD>
<按钮NG点击=添加($指数)>添加新的人< /按钮>
< / TD>
< / TR>
< / TBODY>
JS:
函数TestingCtrl($范围){ $ scope.persons = [{
名称:爱丽丝,
年龄:20
},{
名称:'鲍勃',
年龄:30
}]; $ scope.add =功能(指数){
VAR newPerson =功能(){
返回{
名称: '',
年龄:''
};
};
$ scope.persons.splice(指数+1,0,新newPerson());
}}
我想通了这一点。 这普拉克将ENTER键,所有的箭头键导航(上,下,左,右)。感谢@Armen指着我在正确的方向。
< DIV NG-应用=对myApp>
< DIV NG控制器=TestingCtrl>
<表可导航>
<&THEAD GT;
&所述; TR>
<第i个姓名和LT; /第i
<第i年龄和LT; /第i
百分位>< /第i
< / TR>
< / THEAD>
<&TBODY GT;
< TR NG重复=P人员>
&所述; TD>
<输入类型=文本NG模型=p.name>
< / TD>
&所述; TD>
<输入类型=文本NG模型=p.age>
< / TD>
&所述; TD>
<按钮NG点击=添加($指数)>添加新的人< /按钮>
< / TD>
< / TR>
< / TBODY>
< /表>
< / DIV>
angular.module(对myApp,[])
.controller(TestingCtrl,[$范围
功能TestingCtrl($范围){
$ scope.persons = [{
名称:爱丽丝,
年龄:20
},{
名称:'鲍勃',
年龄:30
}]; $ scope.add =功能(指数){
VAR newPerson =功能(){
返回{
名称: '',
年龄:''
};
};
$ scope.persons.splice(指数+1,0,新newPerson());
} }
])
.directive('导航的',函数(){
返回功能(范围,元素,属性){ element.on(键press.mynavigation','输入[类型=文本],handleNavigation);
功能handleNavigation(五){ VAR箭头= {左:37,最高:38,右:39,下降:40}; //选取所有焦点
element.find(输入)。KEYDOWN(函数(五){ //快捷键不是方向键等按键
如果($ .inArray(e.which,[arrow.left,arrow.up,arrow.right,arrow.down])小于0){
返回;
} VAR输入= e.target;
VAR TD = $(e.target).closest('TD');
VAR的moveTo = NULL; 开关(e.which){ 案例arrow.left:
{
如果(input.selectionStart == 0){
的moveTo = TD preV('TD:有(输入,文本区域)')。
}
打破;
}
案例arrow.right:
{
如果(input.selectionEnd == input.value.length){
的moveTo = td.next('TD:有(输入,文本区域)');
}
打破;
} 案例arrow.up:
案例arrow.down:
{ VAR TR = td.closest('TR');
VAR POS = TD [0] .cellIndex; VAR moveToRow = NULL;
如果(e.which == arrow.down){
moveToRow = tr.next('TR');
}
否则,如果(e.which == arrow.up){
moveToRow = TR preV('TR')。
} 如果(moveToRow.length){
的moveTo = $(moveToRow [0] .cells [POS]);
} 打破;
} } 如果(的moveTo&安培;&安培; moveTo.length){ 亦即preventDefault(); moveTo.find('输入,文本区域')。每个(函数(I,输入){
input.focus();
input.select();
}); } });
VAR键= e.key code? e.key code:e.which;
如果(关键=== 13){
VAR focusedElement = $(e.target);
VAR nextElement = focusedElement.parent()next()方法。
如果(nextElement.find('输入')长方式> 0){
。nextElement.find(输入)专注();
}其他{
。nextElement = nextElement.parent()的next()找到('输入')第();
nextElement.focus();
}
}
}
};
})
我已经从不同的来源做了SOM复制/粘贴。需要重构。
I'm trying to port a special table/grid form made in Windows (Delphi VCL) to an Angular app.
A simplified version of the angular app can be tested here: jsFiddle demo.
User can add as many rows as he wants, as demonstrated in the jsFiddle.
The question is: Is it possible to solve the following with an Angular directive or some other Angular magic?
- jump to next cell (cell to the right or new line) when enter key is pressed.
- jump to cell directly beneath on arrow down.
- jump to cell directly above on arrow up.
HTML:
<tbody>
<tr ng-repeat="p in persons">
<td>
<input ng-model="p.name">
</td>
<td>
<input ng-model="p.age">
</td>
<td>
<button ng-click="add($index)">Add new person</button>
</td>
</tr>
</tbody>
JS:
function TestingCtrl($scope) {
$scope.persons = [{
name: 'Alice',
age: 20
}, {
name: 'Bob',
age: 30
}];
$scope.add = function(index) {
var newPerson = function() {
return {
name: '',
age: ''
};
};
$scope.persons.splice(index + 1, 0, new newPerson());
}
}
I figured this out. This Plunk will navigate on enter key AND all arrow keys (up, down, left, right). Thanks @Armen for pointing me in the right direction.
<div ng-app="myApp">
<div ng-controller="TestingCtrl">
<table navigatable>
<thead>
<tr>
<th>Name</th>
<th>Age</th>
<th></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="p in persons">
<td>
<input type="text" ng-model="p.name">
</td>
<td>
<input type="text" ng-model="p.age">
</td>
<td>
<button ng-click="add($index)">Add new person</button>
</td>
</tr>
</tbody>
</table>
</div>
angular.module("myApp", [])
.controller("TestingCtrl", ["$scope",
function TestingCtrl($scope) {
$scope.persons = [{
name: 'Alice',
age: 20
}, {
name: 'Bob',
age: 30
}];
$scope.add = function(index) {
var newPerson = function() {
return {
name: '',
age: ''
};
};
$scope.persons.splice(index + 1, 0, new newPerson());
}
}
])
.directive('navigatable', function() {
return function(scope, element, attr) {
element.on('keypress.mynavigation', 'input[type="text"]', handleNavigation);
function handleNavigation(e) {
var arrow = {left: 37, up: 38, right: 39, down: 40};
// select all on focus
element.find('input').keydown(function(e) {
// shortcut for key other than arrow keys
if ($.inArray(e.which, [arrow.left, arrow.up, arrow.right, arrow.down]) < 0) {
return;
}
var input = e.target;
var td = $(e.target).closest('td');
var moveTo = null;
switch (e.which) {
case arrow.left:
{
if (input.selectionStart == 0) {
moveTo = td.prev('td:has(input,textarea)');
}
break;
}
case arrow.right:
{
if (input.selectionEnd == input.value.length) {
moveTo = td.next('td:has(input,textarea)');
}
break;
}
case arrow.up:
case arrow.down:
{
var tr = td.closest('tr');
var pos = td[0].cellIndex;
var moveToRow = null;
if (e.which == arrow.down) {
moveToRow = tr.next('tr');
}
else if (e.which == arrow.up) {
moveToRow = tr.prev('tr');
}
if (moveToRow.length) {
moveTo = $(moveToRow[0].cells[pos]);
}
break;
}
}
if (moveTo && moveTo.length) {
e.preventDefault();
moveTo.find('input,textarea').each(function(i, input) {
input.focus();
input.select();
});
}
});
var key = e.keyCode ? e.keyCode : e.which;
if (key === 13) {
var focusedElement = $(e.target);
var nextElement = focusedElement.parent().next();
if (nextElement.find('input').length > 0) {
nextElement.find('input').focus();
} else {
nextElement = nextElement.parent().next().find('input').first();
nextElement.focus();
}
}
}
};
})
I have done som copy/paste from different sources. Needs refactoring.
这篇关于在AngularJS表键盘导航的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!