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

답변:


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 키 누르기 또는 키업 이벤트에 바인딩해야합니다. 일반적으로 사용자 지정 지시문이 필요하지만 AngularUI 라이브러리에는 멋진 키 누르기 솔루션이 이미 설정되어 있습니다. http://angular-ui.github.com/을 참조하십시오

angularUI lib를 추가하면 코드는 다음과 같습니다.

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

또는 Enter 키 누르기를 각 개별 필드에 바인딩 할 수 있습니다.

또한 간단한 keypres 지시문을 작성하려면이 SO 질문을 참조하십시오. AngularJS에서 onKeyUp을 어떻게 감지합니까?

편집 (2014-08-28) :이 답변을 작성할 당시 ng-keypress / ng-keyup / ng-keydown은 AngularJS에서 기본 지시문으로 존재하지 않았습니다. 아래 주석에서 @ darlan-alves는 다음과 같은 훌륭한 솔루션을 제공합니다.

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


9
양식 안에 제출 버튼이있는 경우에만 작동합니다.
ali

3
또한 이것은 <form>이어야하며 내가 사용하는 경향이있는 <someElement ng-form = ""...>에서는 작동하지 않는 것 같습니다.
John Culviner

1
메모를 남기기 만하면 : 여기서 끝났는데 제출 버튼이 작동하지 않으면 제출 기능에 잘못된 이름을 사용했을 수 있습니다. 입력 버튼 제출이 다시 작동 하도록 해당 기능 이름을 가진 ng-submit="join()"등록 컨트롤러를 어리석게 사용 하고있었습니다 . $scope.join = function() {...}foo()
테스터

1
이 답변을 작성할 당시, ng-keypress / ng-keyup은 Angular에 존재하지 않았습니다
eterps

69
ng-keyup="$event.keyCode == 13 && myFunc()"정말 멋진 :)
Gonchar는

286

양식없이 함수를 호출하려면 내 ngEnter 지시문을 사용할 수 있습니다.

자바 스크립트 :

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>

나는 내 트위터 와 내 요지 계정 에 다른 멋진 지시를 제출 합니다 .


2
페이지에서 입력 할 때마다이를 트리거 할 수있는 영리한 방법이 있습니까?
Derek Adair

1
@EpokK 전체 양식에 대해 Enter 키를 비활성화하고 싶습니다. 어떻게 할 수 있습니까? (Enter로 양식 제출을 피하고 싶습니다)
Antonio Max

47
매우 훌륭하지만 AngularJ의 추천에 따라 공식 릴리스가 나중에 동일한 이름을 사용하는 경우 ng- 접두어가 붙은 지시문, 서비스 또는 필터를 작성하지 않아야합니다.
닐 S

5
훌륭한 솔루션. 방금 이름을 keyBind로 변경하고이 줄 "if (event.which === 13) {"를이 "if (event.which === Number (attrs.key)) {"로 변경 한 다음 입력을 "< input type = "text"bind-key = "doSomething ()"key = "13"> "다른 키 이벤트에 재사용 할 수 있습니다.
Brian F

4
중요 : 쉼표없이 keydownkeypress이벤트를 구분하여 구분하면 둘 다 동시에 실행될 수 있습니다. $ rootScope : inprog 오류가 발생할 가능성이 있습니다. 이들 사이에 쉼표를 추가하면 분리형이 만들어지고 $ 다이제스트 주기만 발생합니다. 단일 문자이므로 편집 내용을 적용 할 수 없습니다.
Ryan Miller

197

입력이 하나만있는 경우 양식 태그를 사용할 수 있습니다.

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

둘 이상의 입력이 있거나 양식 태그를 사용하지 않거나 특정 필드에 Enter 키 기능을 연결하려는 경우 다음과 같이 특정 입력에 인라인 할 수 있습니다.

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

2
이것은 자신의 지시를 작성하지 않아도이 작업을 수행하는 영리한 방법입니다.
Charlie Martin

59
더 짧은 : <input ng-keyup = "$ event.keyCode == 13 && myFunc ()"... />
Darlan Alves 2016

잘 작동하고 ng-keyup 지시문을 사용했지만 큰 문제가 있습니다. 하나의 텍스트 필드 만 있으면 완전한 양식 (포스트 백)을 제출하지만 원하지 않습니다. 이미 ng-keyup = "$ event.keyCode == 13 && onTextBoxKeyUp ($ event)"및 "event.preventDefault ();"함수에서 시도했지만; (
SharpNoiZy

이것은 짧지 만 DRY 접근 방식을 생각하면 지시문을 작성하고 지시문과 함께 사용합니다.
Atul Chaudhary

상황에 따라 문제가 될 수 있습니다- '뒤로'와 '다음'버튼이있는 두 개의 버튼 (인터페이스와 같은 마법사)이있는 양식이 있습니다 .'enter '키를 클릭하면 기본 동작은 뒤로 버튼입니다. 위의 코드를 사용할 때 뒤로 버튼을 클릭하면 먼저 클릭 한 다음 myFunction () 코드가 호출됩니다 (마법사의 다음 부분으로 이동하십시오). 그래서 마법사는 잠시 뒤로 돌아가서 계속 진행합니다. @EpokK의 솔루션은 나에게 완벽하게 작동합니다.
Vishwajeet Vatharkar

33

주어진 답변보다 좀 더 확장 가능하고 의미있는 것을 원했기 때문에 내장 객체와 비슷한 방식으로 자바 스크립트 객체를 취하는 지시문을 작성했습니다 ngClass.

HTML

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

객체의 값은 지시문 범위의 맥락에서 평가됩니다. 작은 따옴표로 묶어야합니다. 그렇지 않으면 지시문이로드 될 때 모든 함수가 실행됩니다 (!)

그래서 예를 들면 : esc : 'clear()'대신esc : clear()

자바 스크립트

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

또한 Object와 함께 함수를 변수로 사용하면 함수가 두 번 이상 발생합니다. 아래 코드는 이것을 실행할 때 2+ 항목을 제거합니다. key-bind = "{입력 : 'vm.removeItem (item)'}"
MaylorTaylor

1
@MaylorTaylor 첫 번째 문제에 대한 따옴표의 다른 유형, 즉 사용'vm.doTheThing("myVar")'
AlexFoxGill


14

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

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

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가 두 양식 중 하나에서 제출을 호출 할 수 있습니다. 둘 다에 하나의 양식 태그를 사용하는 경우 제출 단추를 포함해야합니다.


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 클릭 동작을 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);
            });
        }
    };
});
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.