AngularJS ile Enter tuşuna basıldığında formu gönder


364

Bu özel durumda, Enter tuşuna bastığımda bu girişlerin bir işlevi çağırmasını sağlamak için hangi seçeneklere ihtiyacım var?

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

Yanıtlar:


518

Açısal bunu kutudan çıkarır. Form öğenizde ngSubmit'i denediniz mi?

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

DÜZENLEME: Gönderme düğmesi ile ilgili yorum başına, aşağıdaki öğelerin çözümünü sunan bir gönderme düğmesi olmadan enter tuşuna basarak form gönderme sayfasına bakın :

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

Gizli gönderme düğmesi çözümünü beğenmezseniz, Enter tuşuna basın veya keyup olayına bir denetleyici işlevi bağlamanız gerekir. Bu normalde özel bir yönerge gerektirir, ancak AngularUI kütüphanesi önceden kurulmuş hoş bir tuşa basma çözümüne sahiptir. Bkz. Http://angular-ui.github.com/

AngularUI lib'sini ekledikten sonra, kodunuz şöyle bir şey olacaktır:

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

veya enter tuşa basmayı her bir alana bağlayabilirsiniz.

Ayrıca, basit bir keypres yönergesi oluşturmak için şu SO sorularına bakın: AngularJS'de onKeyUp'ı nasıl tespit edebilirim?

DÜZENLEME (2014-08-28): Bu yanıt yazıldığı sırada AngularJS'de ng-keypress / ng-keyup / ng-keydown yerel yönergeler olarak mevcut değildi. Aşağıdaki yorumlarda @ darlan-alves ile oldukça iyi bir çözüm var:

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


9
Yalnızca formun içinde bir gönder düğmesi varsa da çalışır.
ali

3
Ayrıca bunun bir <form> olması gerektiğini unutmayın, bunu kullanma eğilimim <someElement ng-form = "" ...> üzerinde çalışmaz.
John Culviner

1
Sadece bir not bırakarak: Buraya geldiyseniz ve gönderme düğmeleri sizin için çalışmıyorsa, gönderme işleviniz için kötü bir ad kullanıyor olabilirsiniz. Aptalca ng-submit="join()"bir kayıt denetleyicisi için kullanıyordum $scope.join = function() {...}ve bu işlev adını foo()enter-button gönderimi tekrar çalışacak şekilde değiştiriyordum.
tester

1
Bu cevap yazıldığı sırada
Angular'da

69
ng-keyup="$event.keyCode == 13 && myFunc()"Gerçekten harika :)
Gonchar Denys

286

Fonksiyonu form olmadan çağırmak istiyorsanız, ngEnter yönergesimi kullanabilirsiniz:

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>

Twitter ve gist hesabım hakkında başkalarına harika direktifler sunuyorum .


2
Sayfanızdayken enter tuşuna bastıklarında bunu tetiklemenin akıllıca bir yolu var mı?
Derek Adair

1
@EpokK Tüm form için enter tuşunu devre dışı bırakmak istiyorum, bunu nasıl yapabilirim? (Enter ile form gönderilmesini önlemek istiyorum)
Antonio Max

47
çok güzel, ancak AngularJs'ın tavsiyesine göre, resmi bir sürümün daha sonra aynı adı kullanması durumunda, ng- ile başlayan yönergeler, hizmetler veya filtreler oluşturmamalısınız.
Neil S

5
Harika bir çözüm. Ben sadece keyBind ve bu satırı "if (event.which === 13) {" bu "if (event.which === Number (attrs.key)) {" Ve sonra benim giriş "< input type = "text" bind-key = "doSomething ()" key = "13"> "böylece farklı anahtar olaylar için tekrar kullanabilirim.
Brian F

4
ÖNEMLİ: Sınırlamaları kaldırmak için virgül kullanmadan keydownve keypressolaylarını eklemek, her ikisinin de aynı anda tetiklenebileceği anlamına gelir. Bu, $ rootScope: inprog hatalarına neden olabilir. Aralarına virgül eklemek ayrılır ve yalnızca $ digest döngüsünün gerçekleşmesini sağlar. Yalnızca tek bir karakter olduğu için düzenleme uygulanamadı.
Ryan Miller

197

Yalnızca bir girişiniz varsa form etiketini kullanabilirsiniz.

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

Birden fazla girişiniz varsa veya form etiketini kullanmak istemiyorsanız veya enter-key işlevini belirli bir alana eklemek istiyorsanız, girişi aşağıdaki gibi belirli bir girişe satır içine alabilirsiniz:

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

2
Bu, kendi direktifinizi yazmak zorunda kalmadan bunu yapmanın akıllıca bir yoludur
Charlie Martin

59
Daha da kısa: <input ng-keyup = "$ event.keyCode == 13 && myFunc ()" ... />
Darlan Alves

Harika çalışıyor, ng-keyup yönergesini kullandım, ancak bununla ilgili büyük bir sorunum var, sadece bir metin alanım varsa, tam formu (geri gönderme) gönderir, ancak bunu istemiyorum. Zaten ng-keyup = "$ event.keyCode == 13 && onTextBoxKeyUp ($ event)" ve "event.preventDefault ();" fonksiyonunda denedim, ancak yardımcı olmadı; (
SharpNoiZy

bu daha kısa ama DRY yaklaşımını aklımda tutarak hala direktif yaratıp direktifle kullanacağım.
Atul Chaudhary

Bu bağlama bağlı olarak sorunlu olabilir - Ben 'geri' ve 'sonraki' düğmesi ile, iki düğme (arayüz gibi sihirbaz), bir form var, 'enter' tuşuna tıklayarak varsayılan davranış geri düğmesi. Şimdi, yukarıdaki kodu kullanırken, geri düğmesi İLK TIKLADI ve sonra myFunction () kodu çağrılır (sırayla, sihirbazın bir sonraki bölümüne geçelim) Yani, sihirbazım bir süre GERİ gidiyor ve sonra ileri gidiyor. @ EpokK'nun çözümü benim için mükemmel çalışıyor.
Vishwajeet Vatharkar

33

Verilen cevaplardan biraz daha genişletilebilir / anlamsal bir şey istedim, böylece yerleşik bir javascript nesnesini benzer bir şekilde alan bir yönerge yazdım ngClass:

HTML

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

Nesnenin değerleri direktifin kapsamı bağlamında değerlendirilir - tek tırnak içine alındıklarından emin olun aksi halde direktif yüklendiğinde tüm fonksiyonlar yürütülür (!)

Örneğin: esc : 'clear()'yerineesc : 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]);
                    });
                }
            });
        };
    }]);

İşlevde bir dize değişkeni eklemeye çalıştığımda bir angluarjs HTML ayrıştırma hatası alıyorum. key-bind = "{enter: 'vm.doTheThing (' myVar ')'}"
MaylorTaylor

Ayrıca, bir nesne ile bir işlevi değişken olarak kullanırsanız, işlev birden fazla olur fark ettim. Bunu çalıştırdığınızda aşağıdaki kod 2+ öğeyi kaldırır. key-bind = "{enter: 'vm.removeItem (item)'}"
MaylorTaylor

1
@MaylorTaylor ilk sayı için, farklı türde tırnak kullanın yani'vm.doTheThing("myVar")'
AlexFoxGill


14

Shift + enter desteği ile çok iyi, temiz ve basit bir direktif:

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

Veri doğrulamasını da istiyorsanız

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

Buradaki önemli ekleme, $loginForm.$validişlevi çalıştırmadan önce formu doğrulayacaktır. Doğrulama için bu sorunun kapsamı dışında başka özellikler eklemeniz gerekecektir.

İyi şanslar.


2

Gizli bir gönderme düğmesi olması durumunda ngShow yönergesini kullanabileceğinizi ve şu şekilde false olarak ayarlayabileceğinizi belirtmek istedim:

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>daha da kısadır. Görünmez bir düğmenin değerini ayarlamanıza gerek yoktur.
musa

Benim anlayışımdı ng-gönderme yönergesini tetiklemek için, bir girdi type="submit"... Sanırım değer göz ardı edilebilir ama birincisi gerekli olduğuna inanıyorum.
landesko

1

Ng-gönder kullanın ve her iki girişi de ayrı form etiketlerine sarın:

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

Her girdi alanını kendi form etiketinde sarmalamak ENTER komutunun her iki formda da gönderilmesini sağlar. Her ikisi için de bir form etiketi kullanırsanız, bir gönderme düğmesi eklemeniz gerekir.


0

Satır içi stilleri tekrarlamak yerine bir CSS sınıfı kullanarak biraz daha temiz olacak.

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 - İşte temel bir onaylama / uyarı önyükleme yöntemi için kullandığım, <form>

(İstediğiniz şey için jQuery tıklama işlemini devre dışı bırakın ve data-easy-dismisskalıcı etiketinize ekleyin )

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);
            });
        }
    };
});
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.