在AngularJS表键盘导航 [英] Keyboard navigation in AngularJS table

查看:96
本文介绍了在AngularJS表键盘导航的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想端口在Windows(Delphi的VCL)作出一个角度应用一个特殊的表/网格的形式。

角应用的

一个简化版可以在这里进行测试:的jsfiddle演示

他想,作为证明的jsfiddle用户可以添加任意多行。

现在的问题是:是否有可能解决与角指令或某些其他角魔以下


  1. 跳转到下一个单元(单元向右或新行)回车键时为pressed。

  2. 跳转到小区正下方的向下箭头。

  3. 跳转到电池正上方的箭头了。

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指着我在正确的方向。

 < D​​IV NG-应用=对myApp>
< D​​IV 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?

  1. jump to next cell (cell to the right or new line) when enter key is pressed.
  2. jump to cell directly beneath on arrow down.
  3. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆