Antonio Max
Antonio Max

Reputation: 8825

Prevent form submission on enter key

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

Answers (15)

ESP32
ESP32

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

Crowdpleasr
Crowdpleasr

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

pouyada
pouyada

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

Radha vedak
Radha vedak

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

Kenny DiFiore
Kenny DiFiore

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

Evgeny Kokhanovsky
Evgeny Kokhanovsky

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

Jamie Kemp
Jamie Kemp

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

user5512816
user5512816

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

Mohit Aneja
Mohit Aneja

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

Antonio Max
Antonio Max

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

okm
okm

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

Michael Kl&#246;pzig
Michael Kl&#246;pzig

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

McMeep
McMeep

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

tocallaghan
tocallaghan

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

user2643882
user2643882

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

Related Questions