简体   繁体   中英

Angular2 prevent form submission on press of the enter key from within a directive

I have a custom directive which is implemented on a <input type="text" /> element:

<form #testForm="ngForm" (ngSubmit)="submit()">
    <input type="text" name="testInput" testDirective />
    <button type="submit">Submit</button>
</form>

The directive has a HostListener on the keyup event:

@Directive({
    selector: '[testDirective]'
})
export class TestDirective {
    @HostListener('keyup', ['$event'])
    onkeyup(event: any)
    {
        // Do stuff

        if (event.keyCode == 13) { // 13 = enter
            event.stopPropagation();
            return false;
        }
    }
}

As you can see I've used event.stopPropogation() and return false in line with suggestions from other questions but this isn't working and the form is still being submitted when the enter key is pressed.

However if I put (keydown.enter)="$event.preventDefault()" onto the input element itself, it has the desired effect and prevents the form submission.

<input type="text" name="testInput" testDirective (keydown.enter)="$event.preventDefault()" />

This method isn't particularly desirable to me as I'd like to programatically control when the enter key press disables the form submission.

Does anybody have any ideas why the stopPropagation() / return false approach isn't working in this instance?

the error is simply a keyup/down mistake:

@Directive({
  selector: '[testDirective]'
})
export class TestDirectiveDirective {
  @HostListener('keydown', ['$event']) //keydown, not keyup
  onKeyDown(event: any) {
    // Do stuff
    if (event.keyCode === 13) { // 13 = enter
      return false;
    }
  }
}

By the way, stopPropagation is unnecessary in this instance as well, at least from my (admittedly limited) testing. YMMV

The difference between your two approaches is that one uses event.stopPropogation() and the other uses event.preventDefault() . Notice in the one that works, you are using event.preventDefault() . From the Web API docs , Event.stopPropogation does the following:

Prevents further propagation of the current event in the capturing and bubbling phases.

In other words, the event still fires, but it is not permitted to bubble up the DOM tree. In order to actually stop the event, you want to use Event.preventDefault , as you are in the output binding used in your second approach. Also, from the Web API docs :

[ Event.preventDefault ] tells the user agent that if the event does not get explicitly handled, its default action should not be taken as it normally would be.

Essentially, this onkeyup function should do what you want:

  @HostListener('keyup', ['$event'])
  onkeyup(event: any) {
    // Do stuff

    if (event.keyCode == 13) { // 13 = enter
        event.preventDefault();
        return false;
     }
   }

The triggering is caused by the fact that you're in a form, and you click on a submit-type input.

Remove your form tag, change your input by a button with a click event, and you will be good to go.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM