【问题标题】:angularjs move focus to next control on enterangularjs在输入时将焦点移动到下一个控件
【发布时间】:2013-08-06 17:39:14
【问题描述】:

最好的方法是什么,当在表单中按回车键时,焦点转到下一个输入,而不是使用 angularjs 提交表单。

我有一个包含很多字段的表单,客户习惯于按 Enter 键移动到下一个输入(来自桌面应用程序)。当用户点击回车时,angularjs 会保存表单。我喜欢改变这一点。有可能吗?

【问题讨论】:

  • 我建议为此编写一个指令。

标签: angularjs


【解决方案1】:

我建议制定一个自定义指令。像这样的东西。我还没有测试过。

.directive('focus', function() {
  return {
    restrict: 'A',
    link: function($scope,elem,attrs) {

      elem.bind('keydown', function(e) {
        var code = e.keyCode || e.which;
        if (code === 13) {
          e.preventDefault();
          elem.next().focus();
        }
      });
    }
  }
});

类似的东西应该可以。你可能需要调整一些东西。祝你好运。

【讨论】:

  • 谢谢,我会努力的。我需要找到一种方法来防止在输入时提交表单(但不知道您的代码是否阻止了这种情况)
  • 我编辑了它,它运行良好。我测试了它。巴姆。只需在您想以这种方式工作的任何输入元素中加上“焦点”一词即可。
  • 一个变化,使用这个以获得更可用的版本。 elem.nextAll('input').first().focus();
  • 编写此答案时,这些答案是在 Angular.Element 方法中构建的。很容易更改为 addEvenyListener 和 nextSibling
【解决方案2】:

创建自定义指令:

.directive('nextOnEnter', function () {
    return {
        restrict: 'A',
        link: function ($scope, selem, attrs) {
            selem.bind('keydown', function (e) {
                var code = e.keyCode || e.which;
                if (code === 13) {
                    e.preventDefault();
                    var pageElems = document.querySelectorAll('input, select, textarea'),
                        elem = e.srcElement || e.target,
                        focusNext = false,
                        len = pageElems.length;
                    for (var i = 0; i < len; i++) {
                        var pe = pageElems[i];
                        if (focusNext) {
                            if (pe.style.display !== 'none') {
                                angular.element(pe).focus();
                                break;
                            }
                        } else if (pe === elem) {
                            focusNext = true;
                        }
                    }
                }
            });
        }
    }
})

【讨论】:

  • 不得不做一些调整。一:e.srcElement 特定于旧 IE,因此 e.srcElement || e.target 可以代替。 pe === e.srcElement 需要是 pe === elempe.focus() 变成 angular.element(pe).focus()
  • 太棒了。这行得通。我唯一的问题是它不适用于 select / md-select。我们能做点什么吗?
  • 不错.. 但它不适用于 tabindex 属性。但它比其他答案更好。
【解决方案3】:

这是我最终得到的指令(感谢 Zack Argyle):

    angular.module('myApp').directive("nextFocus", nextFocus);

    /** Usage:
      <input next-focus id="field1">
      <input next-focus id="field2">
      <input id="field3">
      Upon pressing ENTER key the directive will switch focus to
      the next field id e.g field2
      The last field should not have next-focus directive to avoid
      focusing on non-existing element.
      Works for Web, iOS (Go button) & Android (Next button) browsers, 
    **/

    function nextFocus() {
      var directive = {
        restrict: 'A',
        link: function(scope, elem, attrs) {
          elem.bind('keydown', function(e) {
            var partsId = attrs.id.match(/field(\d{1})/);
            var currentId = parseInt(partsId[1]);

            var code = e.keyCode || e.which;
            if (code === 13) {
              e.preventDefault();
              document.querySelector('#field' + (currentId + 1)).focus();
            }
          });
        }
      };
      return directive;

    }

【讨论】:

    【解决方案4】:

    我尝试了这个解决方案。正如宣传的那样,它需要一些调整。以下是最终为我工作的内容:

    .directive("focus", function () {
            return {
                restrict: "A",
                link: function ($scope, elem, attrs) {
                    var focusables = $(":focusable");
                    elem.bind("keydown", function (e) {
                        var code = e.keyCode || e.which;
                        if (code === 13) {
                            var current = focusables.index(this);
                            var next = focusables.eq(current + 1).length ? focusables.eq(current + 1) : focusables.eq(0);
                            next.focus();
                            e.preventDefault();
                        }
                    });
                }
            }
    

    请注意,为了让:focusable 伪函数工作,您需要引用 JQueryUI。 (最新版本 1.11.4 对我有用)

    【讨论】:

      【解决方案5】:

      这是我最终得到的指令(感谢 Zack Argyle 和 Oleg):

      app.directive("nextFocus", function () {

          /** Usage:
            <input next-focus tabindex="0" id="field1">
            <input next-focus tabindex="1" id="field2">
            <input id="field3">
            Upon pressing ENTER key the directive will switch focus to
            the next field id e.g field2
            The last field should not have next-focus directive to avoid
            focusing on non-existing element.
            Works for Web, iOS (Go button) & Android (Next button) browsers, 
          **/
          var directive = {
              restrict: 'A',
              link: function (scope, elem, attrs) {
                  elem.bind('keydown', function (e) {
                      var code = e.keyCode || e.which;
                      if (code === 13) {
                          try {
                              if (attrs.tabindex != undefined) {
                                  var currentTabIndex = attrs.tabindex;
                                  var nextTabIndex = parseInt(attrs.tabindex) + 1;
                                  $("[tabindex=" + nextTabIndex + "]").focus();
                              }
                          } catch (e) {
      
                          }
                      }
                  });
              }
          };
          return directive;
      
      });
      

      【讨论】:

      • 不想使用jQuery怎么办?
      【解决方案6】:

      基于 wolcy97 的回答,但仅使用角度

       /** Usage:
        <input next-focus tabindex="0">
        <input next-focus tabindex="1">
        <input tabindex="2">
        Upon pressing ENTER key the directive will switch focus to
        the next tabindex.
        The last field should not have next-focus directive to avoid
        focusing on non-existing element.
        Works for Web, iOS (Go button) & Android (Next button) browsers, 
      **/ 
       app.directive('nextFocus', [function() {
        return {
          restrict: 'A',
          link: function(scope, elem, attrs) {
            elem.bind('keydown', function(e) {
              var code = e.keyCode || e.which;
              if (code === 13) {
                e.preventDefault();
                try {
                  if (attrs.tabindex !== undefined) {
                    var currentTabeIndex = attrs.tabindex;
                    var nextTabIndex = parseInt(currentTabeIndex) + 1;
                    var elems = document.querySelectorAll("[tabindex]");
                    for (var i = 0, len = elems.length; i < len; i++) {
                      var el = angular.element(elems[i]);
                      var idx = parseInt(el.attr('tabindex'));
                      if (idx === nextTabIndex) {
                        elems[i].focus();
                        break;
                      }
                    }
                  }
                } catch (e) {
                  console.log('Focus error: ' + e);
                }
              }
            });
          }
        };
      }]);
      

      【讨论】:

      • 与 tabindex 配合得非常好。谢谢!
      【解决方案7】:

      纯 JavaScript 以 TAB 形式输入

      angular.module('app').directive('tabNext', function () {
      return {
          restrict: 'A',
          link: function (scope, elem) {
      
              elem.bind('keyup', function (e) {
                  var code = e.keyCode || e.which;
                  if (code === 13) {
                      e.preventDefault();
                      var eIDX = -1;
                      for (var i = 0; i < this.form.elements.length; i++) {
                          if (elem.eq(this.form.elements[i])) {
                               eIDX = i;
                               break;
                          }
                      }
                      if (eIDX === -1) {
                          return;
                      }
                      var j = eIDX + 1;
                      var theform = this.form;
                      while (j !== eIDX) {
                          if (j >= theform.elements.length){
                              j = 0;
                          }
                          if ((theform.elements[j].type !== "hidden") && (theform.elements[j].type !== "file")
                                  && (theform.elements[j].name !== theform.elements[eIDX].name) 
                                  && (! theform.elements[j].disabled) 
                                  && (theform.elements[j].tabIndex >= 0)) {
                              if (theform.elements[j].type === "select-one") {
                                  theform.elements[j].focus();
                              } else if (theform.elements[j].type === "button") {
                                  theform.elements[j].focus();
                              } else {
                                  theform.elements[j].focus();
                                  theform.elements[j].select();
                              }
                              return;
                              break;
                          }
                          j++;
                      }
                  }
              });
          }
      }});
      

      【讨论】:

        【解决方案8】:
          <table class="table table-striped table-bordered table-hover">
                                                <tr>
                                                    <th>S No</th>
                                                    <th>Stock Id</th>
                                                    <th>Description</th>
                                                    <th>Qty</th>
                                                    <th>UOM</th>
                                                    <th>Rate</th>
                                                    <th>Amount</th>
        
                                                    <th>Add</th>
                                                    <th>Delete</th>
                                                </tr>
                                                <tr ng-repeat="item in stockitems">
                                                    <td>{{$index + 1}}</td>
                                                    <td>
        
                                                        <input type="text" style="width:70px" id="stkid{{$index}}" class="form-control" name="stockid" required insert="Addnewrow();" ng-keyup="moveFocus('desc','amount','stkid','stkid',$index,$event)" ng-blur="getStockitem($index);" typeahead="a.stockitem_code as (a.stockitem_code +' | ' + a.stockitem_name +' | '+ a.rate) for a in stock | filter:$viewValue | limitTo:8" data-ng-model="item.stockid" rows="3" />
                                                    </td>
                                                    <td>
        
                                                        <input type="text" class="form-control" id="desc{{$index}}" name="description" ng-keyup="moveFocus('quantity','stkid','desc','desc',$index,$event)" data-ng-model="item.description" rows="3" />
                                                    </td>
                                                    <td>
        
                                                        <input type="text" style="width:70px" id="quantity{{$index}}" class="form-control" ng-keyup="moveFocus('uom','desc','quantity','quantity',$index,$event)" ng-change="GetAmount($index,'qty');" ng-pattern="/^\d+$/" required name="qty" data-ng-model="item.qty" rows="3" />
                                                    </td>
                                                    <td>
        
                                                        <input type="text" style="width:70px" id="uom{{$index}}" class="form-control" name="uom" ng-keyup="moveFocus('rate','quantity','uom','uom',$index,$event)" data-ng-model="item.uom" required rows="3" />
                                                    </td>
                                                    <td>
        
        
                                                        <input type="text" style="width:70px" id="rate{{$index}}" class="form-control" name="rate" ng-keyup="moveFocus('amount','uom','rate','rate',$index,$event)" required data-ng-model="item.rate" ng-pattern="/^\d{0,9}(\.\d{1,9})?$/" ng-change="GetAmount($index,'rate');" rows="3" />
                                                    </td>
                                                    <td>
        
                                                        <input type="text" style="width:70px" id="amount{{$index}}" class="form-control" ng-keyup="moveFocus('stkid','rate','amount','amount',$index,$event)" name="amount" required data-ng-model="item.amount" rows="3" />
                                                    </td>
        
                                                    <td><span ng-click="AddEstimation($index);"><a>Add</a></span></td>
                                                    <td><span ng-click="DeleterowEstimation($index);"><a>Delete</a></span></td>
                                                </tr>
                                            </table>
        

        【讨论】:

        • 虽然这段代码 sn-p 可以解决问题,但including an explanation 确实有助于提高帖子的质量。请记住,您是在为将来的读者回答问题,而这些人可能不知道您提出代码建议的原因。
        【解决方案9】:
          $scope.moveFocus = function (nextId,prevId,downId,upId,index,event) {
                    debugger;
                    if (event.keyCode == 39) {
                        nextId = nextId + index;
                        $('#' + nextId).focus();
                    }
                    else if(event.keyCode == 37)
                    {
                        prevId = prevId + index;
                        $('#' + prevId).focus();
                    }
                    else if(event.keyCode == 38)
                    {
                        upId = upId + (index - 1);
                        $('#' + upId).focus();
                    }
                    else if(event.keyCode == 40)
                    {
                        downId = downId + (index + 1);
                        $('#' + downId).focus();
                    }
                    else if(event.keyCode==13)
                    {
                        if (nextId == "desc") {
                            nextId = "quantity" + index;
                            $('#' + nextId).focus();
                        }
                        else if(nextId == "uom")
                        {
                            nextId = "stkid" + (index + 1);
                            $('#' + nextId).focus();
                        }
                    }
                };
        

        【讨论】:

        • 参考下面的html
        【解决方案10】:

        按 Enter 键会移动到 DOM 的下一个元素,但元素需要 id 才能设置焦点

        starter.directive('focustonext', function () {
        return {
            restrict: 'A',
            link: function ($scope, selem, attrs) {
                selem.bind('keydown', function (e) {
                    var code = e.keyCode || e.which;
                    if (code === 13) {
                        e.preventDefault();
                        var pageElems = document.querySelectorAll('input, select, textarea'),
                            elem = e.srcElement || e.target,
                            focusNext = false,
                            len = pageElems.length;
                        for (var i = 0; i < len; i++) {
                            var pe = pageElems[i];
                            if (focusNext) {
                                if (pe.style.display !== 'none') {                               
                                    document.getElementById(pe.id).focus();
                                    break;
                                }
                            } else if (pe === elem) {
                                focusNext = true;
                            }
                        }
                    }
                });
            }
           }
        });
        

        谢谢大家..

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-06-30
          • 2020-04-02
          • 1970-01-01
          • 2017-05-08
          • 1970-01-01
          • 1970-01-01
          • 2021-01-13
          相关资源
          最近更新 更多