Reputation: 11045
In this particular case, what options do I have to make these inputs call a function when I press 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');
};
}])
Upvotes: 369
Views: 388810
Reputation: 9546
I focused to below row input in the table
<input ng-keydown="$event.keyCode == 13 && onPressEnter($event)" id="input_0" type="text" >
$scope.onPressEnter = function (event) {
let inputId = event.target.id;
let splited = inputId.split('_');
let newInputId = 'input' + '_' + ((+splited[1]) + 1);
if (document.getElementById(newInputId))
document.getElementById(newInputId).focus();
// else submit form
}
Upvotes: 0
Reputation: 312
you can simply bind @Hostlistener with the component, and rest will take care by it. It won't need binding of any method from its HTML template.
@HostListener('keydown',['$event'])
onkeydown(event:keyboardEvent){
if(event.key == 'Enter'){
// TODO do something here
// form.submit() OR API hit for any http method
}
}
The above code should work with Angular 1+ version
Upvotes: 0
Reputation: 183
FWIW - Here's a directive I've used for a basic confirm/alert bootstrap modal, without the need for a <form>
(just switch out the jQuery click action for whatever you like, and add data-easy-dismiss
to your modal tag)
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);
});
}
};
});
Upvotes: 0
Reputation: 1621
Another approach would be using ng-keypress ,
<input type="text" ng-model="data" ng-keypress="($event.charCode==13)? myfunc() : return">
Submit an input on pressing Enter with AngularJS - jsfiddle
Upvotes: 28
Reputation: 372
Just wanted to point out that in the case of having a hidden submit button, you can just use the ngShow directive and set it to false like so:
HTML
<form ng-submit="myFunc()">
<input type="text" name="username">
<input type="submit" value="submit" ng-show="false">
</form>
Upvotes: 2
Reputation: 23717
If you want data validation too
<!-- 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>
The important addition here is $loginForm.$valid
which will validate the form before executing function. You will have to add other attributes for validation which is beyond the scope of this question.
Good Luck.
Upvotes: 5
Reputation: 2249
If you only have one input you can use the form tag.
<form ng-submit="myFunc()" ...>
If you have more than one input, or don't want to use the form tag, or want to attach the enter-key functionality to a specific field, you can inline it to a specific input as follows:
<input ng-keyup="$event.keyCode == 13 && myFunc()" ...>
Upvotes: 202
Reputation: 1385
Very good, clean and simple directive with shift + enter support:
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);
}
}
});
}
}
});
Upvotes: 14
Reputation: 57
Use ng-submit and just wrap both inputs in separate form tags:
<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>
Wrapping each input field in its own form tag allows ENTER to invoke submit on either form. If you use one form tag for both, you will have to include a submit button.
Upvotes: 1
Reputation: 14208
Angular supports this out of the box. Have you tried ngSubmit on your form element?
<form ng-submit="myFunc()" ng-controller="mycontroller">
<input type="text" ng-model="name" />
<br />
<input type="text" ng-model="email" />
</form>
EDIT: Per the comment regarding the submit button, see Submitting a form by pressing enter without a submit button which gives the solution of:
<input type="submit" style="position: absolute; left: -9999px; width: 1px; height: 1px;"/>
If you don't like the hidden submit button solution, you'll need to bind a controller function to the Enter keypress or keyup event. This normally requires a custom directive, but the AngularUI library has a nice keypress solution set up already. See http://angular-ui.github.com/
After adding the angularUI lib, your code would be something like:
<form ui-keypress="{13:'myFunc($event)'}">
... input fields ...
</form>
or you can bind the enter keypress to each individual field.
Also, see this SO questions for creating a simple keypres directive: How can I detect onKeyUp in AngularJS?
EDIT (2014-08-28): At the time this answer was written, ng-keypress/ng-keyup/ng-keydown did not exist as native directives in AngularJS. In the comments below @darlan-alves has a pretty good solution with:
<input ng-keyup="$event.keyCode == 13 && myFunc()"... />
Upvotes: 522
Reputation: 5260
Will be slightly neater using a CSS class instead of repeating inline styles.
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>
Upvotes: 0
Reputation: 7919
I wanted something a little more extensible/semantic than the given answers so I wrote a directive that takes a javascript object in a similar way to the built-in ngClass
:
<input key-bind="{ enter: 'go()', esc: 'clear()' }" type="text"></input>
The values of the object are evaluated in the context of the directive's scope - ensure they are encased in single quotes otherwise all of the functions will be executed when the directive is loaded(!)
So for example:
esc : 'clear()'
instead of 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]);
});
}
});
};
}]);
Upvotes: 34
Reputation: 38092
If you want to call function without form you can use my ngEnter directive:
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>
I submit others awesome directives on my twitter and my gist account.
Upvotes: 290