使用AngularJS按Enter提交表单


364

在这种情况下,按Enter键时必须使这些输入调用函数的选项是什么?

// HTML view //
<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');
    };
}])

Answers:


518

Angular开箱即用。您是否在表单元素上尝试了ngSubmit

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

编辑:根据有关提交按钮的注释,请参阅通过按Enter而无需提交按钮的方式提交表单,该解决方案包括:

<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>

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

另外,请参阅以下关于创建简单keypres指令的问题: 如何在AngularJS中检测onKeyUp?

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

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


9
仅当我在表单内也有一个提交按钮时,它才起作用。
2013年

3
还要注意,这必须是<form>,它似乎不适用于我倾向于使用的<someElement ng-form =“” ...>。
John Culviner 2014年

1
只是留个便条:如果您到这里为止并且提交按钮对您不起作用,则您的提交功能可能使用了错误的名称。我愚蠢地使用ng-submit="join()"了一个拥有$scope.join = function() {...}并更改该函数名称的foo()输入控制器,以使输入按钮提交再次起作用。
测试人员

1
在撰写此答案时,Angular中不存在ng-
keypress

69
ng-keyup="$event.keyCode == 13 && myFunc()"真的很棒:)
Gonchar Denys 2015年

286

如果要调用不带格式的函数,可以使用我的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>

我在自己的TwitterGist帐户上提交了其他很棒的指令。


2
在他们在您的页面上按下Enter键时,是否有一种聪明的方法来触发它?
德里克·阿黛尔

1
@EpokK我想为整个表格禁用回车键,我该怎么做?(我想避免使用enter提交表单)
Antonio Max

47
非常好,但是按照AngularJs的建议,您不应创建以ng-为前缀的指令,服务或过滤器,以防万一正式版本以后使用相同的名称。
尼尔·S

5
很好的解决方案。我只是将名称更改为keyBind,并将此行“ if(event.which === 13){”更改为“ if(event.which === Number(attrs.key)){”,然后输入“输入type =“ text” bind-key =“ doSomething()” key =“ 13”>“,这样我就可以将其重新用于不同的键事件。
Brian F

4
重要说明:如果同时添加keydownkeypress事件,请不要使用逗号来分隔它们,这意味着它们可能会同时触发。这可能会产生$ rootScope:inprog错误。在它们之间添加逗号会产生析取关系,并确保仅发生$ digest循环。由于该编辑只是一个字符,因此无法应用。
Ryan Miller

197

如果只有一个输入,则可以使用form标签。

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

如果您有多个输入,或者不想使用form标记,或者想要将Enter键功能附加到特定字段,则可以按如下所示将其内联到特定输入:

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

2
这是这样做的,甚至无需编写自己的指令一个聪明的办法
查理·马丁

59
甚至更短:<input ng-keyup =“ $ event.keyCode == 13 && myFunc()” ... />
Darlan Alves 2014年

效果很好,我使用了ng-keyup指令,但是它有一个大问题,如果我只有一个文本字段,他会提交完整的表单(回发),但我不希望这样做。我已经尝试过ng-keyup =“ $ event.keyCode == 13 && onTextBoxKeyUp($ event)”并在函数“ event.preventDefault();”中
尝试过

这是更短的代码,但在我脑海中牢记DRY方法,我仍然会创建指令并将其与指令一起使用。
Atul Chaudhary 2015年

根据上下文,这可能是有问题的-我有一个窗体,其中有两个按钮(类似于向导的界面),带有“后退”和“下一个”按钮,单击“输入”键的默认行为是后退按钮。现在,当使用上面的代码时,先单击后退按钮get的第一个,然后调用myFunction()代码(这反过来,将get转到向导的下一部分)因此,我的向导后退了一段时间,然后前进了。@EpokK的解决方案非常适合我。
Vishwajeet Vatharkar 2015年

33

我想要一些比给定答案更可扩展/语义的东西,所以我写了一条指令,该指令以与内置类似的方式接受javascript对象 ngClass

的HTML

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

在指令范围内评估对象的值-确保将其用单引号引起来,否则在加载指令时将执行所有功能(!)

因此,例如: esc : 'clear()'代替esc : clear()

Java脚本

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')'}”
MaylorTaylor

还应注意,如果我将带有对象的函数用作变量,则函数会发生多次。当我运行此代码时,下面的代码将删除2个以上的项目。key-bind =“ {输入:'vm.removeItem(item)'}”
MaylorTaylor

1
@MaylorTaylor第一期,使用不同类型的引号,即'vm.doTheThing("myVar")'
AlexFoxGill


14

非常好,干净且简单的指令,带有shift +输入支持:

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);
                       }
                 }
            });
        }
    }
});

5

如果您也想要数据验证

<!-- 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在执行功能之前将验证表单。您将不得不添加其他属性来进行验证,这超出了此问题的范围。

祝好运。


2

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

的HTML

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

1
+1 <button ng-show="false"></button>甚至更短。无需设置不可见按钮的值。
musa

据我了解,为了触发ng-submit指令,输入type="submit"... ...我认为可以忽略值,但我相信前者是必要的。
landesko'7

1

使用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可以调用任一表单上的Submit。如果两者都使用一个表单标签,则必须包含一个提交按钮。


0

使用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>

0

FWIW-这是我用于基本确认/警报引导程序模式的指令,不需要 <form>

(只需将jQuery click动作切换为您喜欢的任何方式,然后添加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);
            });
        }
    };
});
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.