【问题标题】:Submit form on pressing Enter with AngularJS使用 AngularJS 按 Enter 提交表单
【发布时间】:2013-03-03 06:22:25
【问题描述】:

在这种特殊情况下,当我按下 Enter 时,我必须使用哪些选项才能使这些输入调用函数?

HTML:

<form>
    <input type="text" ng-model="name" <!-- Press ENTER and call myFunc --> />
    <br />
    <input type="text" ng-model="email" <!-- Press ENTER and call myFunc --> />
</form>
// Controller //
.controller('mycontroller', ['$scope',function($scope) {
    $scope.name = '';
    $scope.email = '';
    // Function to be called when pressing ENTER
    $scope.myFunc = function() {
       alert('Submitted');
    };
}])

【问题讨论】:

    标签: angularjs forms form-submit keypress enter


    【解决方案1】:

    Angular 开箱即用地支持这一点。您是否在表单元素上尝试过ngSubmit

    <form ng-submit="myFunc()" ng-controller="mycontroller">
       <input type="text" ng-model="name" />
        <br />
        <input type="text" ng-model="email" />
    </form>
    

    编辑:根据关于提交按钮的评论,请参阅Submitting a form by pressing enter without a submit button,它给出了解决方案:

    <input type="submit" style="position: absolute; left: -9999px; width: 1px; height: 1px;"/>
    

    如果您不喜欢隐藏提交按钮的解决方案,您需要将控制器功能绑定到 Enter keypress 或 keyup 事件。这通常需要一个自定义指令,但 AngularUI 库已经设置了一个不错的按键解决方案。见http://angular-ui.github.com/

    添加 angularUI 库后,您的代码将类似于:

    <form ui-keypress="{13:'myFunc($event)'}">
      ... input fields ...
    </form>
    

    或者您可以将回车键绑定到每个单独的字段。

    另外,请参阅此 SO 问题以创建简单的 keypres 指令: How can I detect onKeyUp in AngularJS?

    编辑(2014-08-28):在编写此答案时,ng-keypress/ng-keyup/ng-keydown 在 AngularJS 中不作为本机指令存在。在@darlan-alves 下面的 cmets 中有一个很好的解决方案:

    &lt;input ng-keyup="$event.keyCode == 13 &amp;&amp; myFunc()"... /&gt;

    【讨论】:

    • 只有当我在表单中也有一个提交按钮时它才有效。
    • 另请注意,这必须是一个
      它似乎不适用于 这是我倾向于使用的。
    • 留个便条:如果您在这里结束并且提交按钮不适合您,您可能为您的提交功能使用了一个错误的名称。我愚蠢地将ng-submit="join()" 用于具有$scope.join = function() {...} 的注册控制器并将该函数名称更改为foo() 让输入按钮再次工作。
    • 在撰写此答案时,Angular 中不存在 ng-keypress/ng-keyup
    • ng-keyup="$event.keyCode == 13 &amp;&amp; myFunc()" 真棒:)
    【解决方案2】:

    如果你想在没有表单的情况下调用函数,你可以使用我的 ngEnter 指令:

    Javascript

    angular.module('yourModuleName').directive('ngEnter', function() {
            return function(scope, element, attrs) {
                element.bind("keydown keypress", function(event) {
                    if(event.which === 13) {
                        scope.$apply(function(){
                            scope.$eval(attrs.ngEnter, {'event': event});
                        });
    
                        event.preventDefault();
                    }
                });
            };
        });
    

    HTML

    <div ng-app="" ng-controller="MainCtrl">
        <input type="text" ng-enter="doSomething()">    
    </div>
    

    我在my twitter 和我的gist account 上提交了其他很棒的指令。

    【讨论】:

    • 有没有一种聪明的方法可以在他们在您的页面上按 Enter 键时触发?
    • @EpokK 我想禁用整个表单的回车键,我该怎么做? (我想避免使用 enter 提交表单)
    • 非常好,但是根据 AngularJs 的建议,您不应该创建以 ng- 为前缀的指令、服务或过滤器,以防以后官方版本使用相同的名称。
    • 很好的解决方案。我只是将名称更改为 keyBind 并将这一行 "if(event.which === 13) {" 更改为 "if(event.which === Number(attrs.key)) {" 然后我输入 "" 这样我就可以将它重新用于不同的关键事件。
    • 重要提示:同时添加 keydownkeypress 事件而不用逗号分隔它们意味着两者可以同时触发。这可能会产生 $rootScope:inprog 错误。在它们之间添加一个逗号会创建一个析取词,并确保只发生 $digest 循环。无法应用编辑,因为它只有一个字符。
    【解决方案3】:

    如果你只有一个输入,你可以使用表单标签。

    <form ng-submit="myFunc()" ...>
    

    如果您有多个输入,或者不想使用表单标签,或者想将回车键功能附加到特定字段,您可以将其内联到特定输入,如下所示:

    <input ng-keyup="$event.keyCode == 13 && myFunc()" ...>
    

    【讨论】:

    • 这是一种巧妙的方式,甚至无需编写自己的指令
    • 更短:
    • 效果很好,我使用了 ng-keyup 指令,但我有一个大问题,如果我只有一个文本字段,他会提交完整的表单(回发)但我不想要那。我已经尝试过 ng-keyup="$event.keyCode == 13 && onTextBoxKeyUp($event)" 和函数“event.preventDefault();”,但没有帮助;(
    • 这更短,但在我心中保持 DRY 方法我仍然会创建指令并将其与指令一起使用。
    • 这可能有问题,具体取决于上下文 - 我有一个表单,其中有两个按钮(类似向导的界面),带有“后退”和“下一步”按钮,单击“输入”时的默认行为' 键是返回按钮。现在,当使用上面的代码时,首先点击后退按钮,然后调用 myFunction() 代码(这反过来,进入向导的下一部分)所以,我的向导返回一段时间,然后继续前进。 @EpokK 的解决方案非常适合我。
    【解决方案4】:

    我想要一些比给定答案更具可扩展性/语义的东西,所以我编写了一个指令,该指令以与内置 ngClass 类似的方式采用 javascript 对象:

    HTML

    <input key-bind="{ enter: 'go()', esc: 'clear()' }" type="text"></input>
    

    对象的值在指令范围的上下文中进行评估 - 确保它们用单引号括起来,否则所有函数将在指令加载时执行(!)

    例如: esc : 'clear()' 而不是 esc : clear()

    Javascript

    myModule
        .constant('keyCodes', {
            esc: 27,
            space: 32,
            enter: 13,
            tab: 9,
            backspace: 8,
            shift: 16,
            ctrl: 17,
            alt: 18,
            capslock: 20,
            numlock: 144
        })
        .directive('keyBind', ['keyCodes', function (keyCodes) {
            function map(obj) {
                var mapped = {};
                for (var key in obj) {
                    var action = obj[key];
                    if (keyCodes.hasOwnProperty(key)) {
                        mapped[keyCodes[key]] = action;
                    }
                }
                return mapped;
            }
            
            return function (scope, element, attrs) {
                var bindings = map(scope.$eval(attrs.keyBind));
                element.bind("keydown keypress", function (event) {
                    if (bindings.hasOwnProperty(event.which)) {
                        scope.$apply(function() {
                             scope.$eval(bindings[event.which]);
                        });
                    }
                });
            };
        }]);
    

    【讨论】:

    • 当我尝试在函数中添加字符串变量时,出现 angluarjs HTML 解析错误。 key-bind="{ 输入:'vm.doTheThing('myVar')' }"
    • 还注意到,如果我使用带有对象作为变量的函数,该函数会发生不止一次。当我运行它时,下面的代码会删除 2+ 个项目。 key-bind="{ 输入:'vm.removeItem(item)' }"
    • @MaylorTaylor 对于第一期,使用不同类型的引号,即'vm.doTheThing("myVar")'
    【解决方案5】:

    另一种方法是使用 ng-keypress ,

    <input type="text" ng-model="data" ng-keypress="($event.charCode==13)? myfunc() : return"> 
    

    Submit an input on pressing Enter with AngularJS - jsfiddle

    【讨论】:

      【解决方案6】:

      非常好的、干净和简单的指令,带有 shift + enter 支持:

      app.directive('enterSubmit', function () {
          return {
              restrict: 'A',
              link: function (scope, elem, attrs) {
                  elem.bind('keydown', function(event) {
                       var code = event.keyCode || event.which;
                       if (code === 13) {
                             if (!event.shiftKey) {
                                  event.preventDefault();
                                  scope.$apply(attrs.enterSubmit);
                             }
                       }
                  });
              }
          }
      });
      

      【讨论】:

        【解决方案7】:

        如果你也想要数据验证

        <!-- form -->
        <form name="loginForm">
        ...
          <input type="email" ng-keyup="$loginForm.$valid && $event.keyCode == 13 && signIn()" ng-model="email"... />
          <input type="password" ng-keyup="$loginForm.$valid && $event.keyCode == 13 && signIn()" ng-model="password"... />
        </form>
        

        这里重要的补充是$loginForm.$valid,它将在执行函数之前验证表单。您必须添加其他属性进行验证,这超出了本问题的范围。

        祝你好运。

        【讨论】:

          【解决方案8】:

          只是想指出,在有隐藏提交按钮的情况下,您可以使用 ngShow 指令并将其设置为 false,如下所示:

          HTML

          <form ng-submit="myFunc()">
              <input type="text" name="username">
              <input type="submit" value="submit" ng-show="false">
          </form>
          

          【讨论】:

          • +1 &lt;button ng-show="false"&gt;&lt;/button&gt; 更短。无需设置不可见按钮的值。
          • 我的理解是,为了触发 ng-submit 指令,输入 type="submit" ... 我认为值可以忽略,但我认为前者是必要的。
          【解决方案9】:

          使用 ng-submit 并将两个输入包装在单独的表单标签中:

          <div ng-controller="mycontroller">
          
            <form ng-submit="myFunc()">
              <input type="text" ng-model="name" <!-- Press ENTER and call myFunc --> />
            </form>
          
            <br />
          
            <form ng-submit="myFunc()">
              <input type="text" ng-model="email" <!-- Press ENTER and call myFunc --> />
            </form>
          
          </div>
          

          将每个输入字段包装在其自己的表单标记中允许 ENTER 在任一表单上调用提交。如果您对两者都使用一个表单标签,则必须包含一个提交按钮。

          【讨论】:

            【解决方案10】:

            使用 CSS 类而不是重复内联样式会稍微整洁一些。

            CSS

            input[type=submit] {
                position: absolute;
                left: -9999px;
            }
            

            HTML

            <form ng-submit="myFunc()">
                <input type="text" ng-model="name" />
                <br />
                <input type="text" ng-model="email" />
                <input type="submit" />
            </form>
            

            【讨论】:

              【解决方案11】:

              FWIW - 这是我用于基本确认/警报引导模式的指令,不需要 &lt;form&gt;

              (只需将 jQuery 单击操作切换为您喜欢的任何内容,并将data-easy-dismiss 添加到您的模态标签中)

              app.directive('easyDismiss', function() {
                  return {
                      restrict: 'A',
                      link: function ($scope, $element) {
              
                          var clickSubmit = function (e) {
                              if (e.which == 13) {
                                  $element.find('[type="submit"]').click();
                              }
                          };
              
                          $element.on('show.bs.modal', function() {
                              $(document).on('keypress', clickSubmit);
                          });
              
                          $element.on('hide.bs.modal', function() {
                              $(document).off('keypress', clickSubmit);
                          });
                      }
                  };
              });
              

              【讨论】:

                【解决方案12】:

                你可以简单地将@Hostlistener 与组件绑定,rest 将由它来处理。它不需要绑定其 HTML 模板中的任何方法。

                @HostListener('keydown',['$event'])
                onkeydown(event:keyboardEvent){
                  if(event.key == 'Enter'){
                           // TODO do something here
                           // form.submit() OR API hit for any http method
                  }
                }
                

                以上代码应该适用于 Angular 1+ 版本

                【讨论】:

                  猜你喜欢
                  • 2017-09-28
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2011-05-29
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多