Reputation: 8825
How can I prevent the enter key from submitting the form in angular?
Is there a way to catch the 13 key and disable it or set the form as invalid unless submitting from a button with ID of x?
Thanks
Upvotes: 60
Views: 67984
Reputation: 8709
Other users have already written that [button type="submit"] will cause this trouble. PLEASE NOTE: buttons WITHOUT any type="..." declaration are "submit" by default! So make sure you always use type="button".
Upvotes: 26
Reputation: 4044
The following should work . . . i.e., the form is only submitted on button click, and not on hitting Enter
in the Input boxes. (This definitely works for reactive forms. I didn't test it for template forms).
<form #form [formGroup]="form" METHOD="GET" action="http://localhost:3000/test">
<input placeholder="Enter"/>
<input placeholder="The Dragon"/>
<button type="button" (click)="form.submit()">Submit</button>
</form>
Of course, remember all the imports and declarations:
app.module.ts
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
@NgModule({
imports: [
. . .
FormsModule,
ReactiveFormsModule
]
. . .
})
export class AppModule { }
test.component.ts
import { FormGroup, FormControl } from '@angular/forms';
@Component({
selector: 'app-test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.scss']
})
export class TestComponent {
form: FormGroup = new FormGroup({});
constructor() { }
}
Upvotes: 0
Reputation: 377
so simple, doesn't need to do anything. just add this to your form tag if you are using angular +2
<form (keydown.enter)="$event.preventDefault()" ...>
Upvotes: 12
Reputation: 64
angular.element(document).ready(function () {
angular.element(window).keydown(function () {
if(event.keyCode == 13) {
event.preventDefault();
return false;
}
});
});
Try with this in angularjs controller
Upvotes: 1
Reputation: 176
If you are attempting to prevent the form from being submitted on just a single element, you can add the following ng-keypress handler (this is for Angular 1.x):
<input type="text" name="myField" ng-keypress="keyPressHandler($event)"/>
With the following implementation for keyPressHandler
:
$scope.keyPressHandler = function(e) {
if (e.keyCode === 13) {
e.preventDefault();
e.stopPropagation();
// Perform your custom logic here if any
}
}
Upvotes: 11
Reputation: 21
This is my weird but quick and simple solution without any directives.
HTML:
<form ng-submit='submitForm()'>
<input type='text'>
<button type='submit' ng-mousedown='doSubmit=true'>submit</button>
</form>
Controller:
$scope.submitForm = function() {
if (!$scope.doSubmit) {
return;
}
$scope.doSubmit = false;
console.log('execute some actions');
}
Upvotes: 2
Reputation: 101
I came across this issue. Yes, you would need to remove all type='submit' from your page, and make sure any other buttons have type="button" but then the challenge is still being able to use normal validation submission.
I created a directive that triggers form submission + form states for validation. Replacing:
<button type="submit">
with
<button submit-button type="button">
Directive:
export default /*@ngInject*/ function submitButton($log) {
return ({
require: '^form',
link: link,
restrict: 'A'
});
function link(scope, element, attributes, formCtrl) {
element.on('click', clickHandler);
function clickHandler() {
formCtrl.$setDirty(true);
formCtrl.$setSubmitted(true);
angular.element(element[0].form).triggerHandler('submit');
$log.info('Form Submitted');
}
}
You can still hit ENTER to submit when focused on your submit-button, better for UX and Accessibility I think.
Upvotes: 6
Reputation: 1
A form is submitted when the enter key is clicked while a control within the form has focus. If you register a listener using ng-submit you can intercept this and use prevent defaults to stop the default process (i.e. submitting the form). Have a look at th
Upvotes: 0
Reputation: 428
The easiest solution to this I found is to use input type as button instead of submit and bind the form submit function with ng-click and not using the ng-submit in the form tag.
I hope this helps.
Upvotes: 2
Reputation: 8825
After a couple hours, this weird code was the only thing that worked.
I'm waiting for better answers, won't accept this monster:
app.directive('onKeyup', function() {
return function(scope, elm, attrs) {
var allowedKeys = scope.$eval(attrs.keys);
elm.bind('keydown', function(evt) {
angular.forEach(allowedKeys, function(key) {
if (key == evt.which) {
evt.preventDefault(); // Doesn't work at all
window.stop(); // Works in all browsers but IE
document.execCommand("Stop"); // Works in IE
return false; // Don't even know why it's here. Does nothing.
}
});
});
};
});
and trigger it by using this on all form inputs:
<input on-keyup="bla" keys="[13]" .... />
For now, whenever the user press the enter key, the window try to submit, then fail to do so, not so silently. Ugly but it works.
Edit: keydown is a little better than keyup for the element bind, now enter key fails silently-ish
Upvotes: 12
Reputation: 23871
Check this:
if a form has 2+ input fields and no buttons or input[type=submit] then hitting enter doesn't trigger submit
Thus if your form has 2+ input fields, you could use something like <span ng-click="submit()">Sumbit</span>
to prevent key-trigger of enter key in those input fields.
Upvotes: 6
Reputation: 1225
Since you have ng-click anyways, you could also use <button type="button">
, even inside the form tag. The default behaviour of the button element is type="submit"
, which is what you want to prevent. So, no javascript needed at all!
Upvotes: 110
Reputation: 698
I had a similar problem, I ended up taking the button out of the form.
Seeing as I use ng-click
and everything is binded with ng-model
it doesn't really matter if it's inside the form or not.
I realise this is bad practice but it sure as hell beats writing a custom directive to intercept keystrokes.
Upvotes: 8
Reputation: 9522
Try setting a variable when you click the submit button and checking that it has been set in the form submit.
$scope.click = function () {
$scope.clicked = true;
$scope.submit();
};
$scope.submit = function () {
if ($scope.clicked) {
... submit
} else {
... prevent defaults
}
$scope.clicked = false;
};
See jsfiddle
Upvotes: -1
Reputation: 69
You can catch the default form submit in your controller using ng-submit on the form tag and it will prevent a submit:
http://docs.angularjs.org/api/ng.directive:ngSubmit
alternatively, if you really wanted to catch the key events, there are also directives for that which pass an event you can call stop:
http://docs.angularjs.org/api/ng.directive:ngKeyup
Upvotes: 1