75

I am using Vue.js in my app and have a text input within a form

<div id="myVueForm">
<form>
   <input type="text" v-on="keyup:addCategory | key 'enter'">

   <!-- more form fields -->
   <button type="submit">Submit Form</button>
</form>
</div>

In my Vue instance I have the following

new Vue({
    el: '#myVueForm',

    methods: {
        addCategory: function(e)
        {
           if(e) e.preventDefault();
           console.log("Added a new category, thanks!");
        }
    }
});

Despite the preventDefault() call, when a user presses enter whilst on the text input the form still submits (although the addCategory() method does fire). This behaviour can be demonstrated in this fiddle.

I know I can use jQuery to catch the event and prevent the submit, but I'd like to see if it's possible in Vue to do this as it seems quite a common usage.

Penny Liu
  • 15,447
  • 5
  • 79
  • 98
harryg
  • 23,311
  • 45
  • 125
  • 198
  • I want to be able to submit the form, just not by pressing enter in this particular text input. And that doesn't change anything. You can remove the button altogether and the form will still submit on enter – harryg Jun 26 '15 at 10:12
  • 2
    Thank you for supplying a fiddle. Not enough people do that these days. – Drakes Jun 26 '15 at 10:13

11 Answers11

95

Here's a solution for Vue.js 2.x:

<input type='text' v-on:keydown.enter.prevent='addCategory' />
bradlis7
  • 3,375
  • 3
  • 26
  • 34
  • 2
    Your edit was rejected, but it was more in line with the question. I couldn't figure out how to "accept" it, but I made the changes. Thanks @Leng. – bradlis7 Feb 22 '17 at 16:34
  • 14
    There is no need to add the `addCategory` method, just `` is sufficient – Suau Sep 27 '18 at 09:38
  • This worked for me. Just to add, you must make sure that it is v-on:keydown.enter.prevent to make it work. – Kevz Oct 10 '19 at 08:10
71

The submit is always fired on keydown. So use keydown instead of keyup.

<input type="text"  v-on="keydown:addCategory | key 'enter'">
Sebastian Nette
  • 7,364
  • 2
  • 17
  • 17
68

why dont just disable the form submission ?

<form v-on:submit.prevent><input .../></form>
Clem
  • 2,150
  • 15
  • 17
  • 24
    And for modern Vue: @submit.prevent – Michael Giovanni Pumo Sep 12 '17 at 22:31
  • 4
    This won't work if you form only contains 1 element, then the input always gets submitted. See https://stackoverflow.com/a/12123196/151237 – Coreus Oct 06 '17 at 12:51
  • 2
    Yes it will. It s not preventing the form to be submitted. It catch the event and prevent the default behavior of the browser form. Submit.prevent is like v-on:submit=(e) => e.preventDefault(). – Clem Oct 06 '17 at 13:07
19

You can use for disable the submit event:

<form @submit.prevent="">

and then when you need to do a form submit use something like this:

<button type="submit" @click="mySubmitMethod"> Send </button>
cjeronimomx
  • 806
  • 10
  • 9
11

You can use this:

HTML

<form name="..." @submit.prevent="onSubmitMethod">

JS

methods: {
  onSubmitMethod() {

  }
}
ErezSo
  • 15
  • 1
  • 2
10

Vue.js 1.0 you could do:

<input type="text" @keyup.enter.prevent="addCategory">
Ryun
  • 715
  • 6
  • 10
  • 14
    You need to use `@keydown`, otherwise the form will already have been submitted and you can't prevent it anymore. – Lukas Knuth Jul 25 '16 at 14:26
7

For those simply looking to prevent a form submitting on enter, but not wanting to trigger any method on the input, you can simply do:

<input type="text" @keypress.enter.prevent />

Or on a custom component include the native modifier:

<custom-input type="text" @keypress.enter.native.prevent />

Beautifully readable and succinct.

fredrivett
  • 5,419
  • 3
  • 35
  • 48
2

I had an edge case where an input was within a popup, and the popup was for only part of the form. I wanted to prevent enter from submitting the form while the popup was open, but not altogether. This worked:

<input type="text" @keydown.enter.prevent = "" /> 
crash springfield
  • 1,072
  • 7
  • 17
  • 33
1

You can get event from the HTML and send it to Vue just to preventDefault like so:

HTML

<input type="text" v-on:keydown.13="my_method($event)">

JS

methods: {
    my_method(event){
        // do something
        if (event) event.preventDefault();
        if (event) event.stopPropagation();
    },
},
Yevgeniy Afanasyev
  • 37,872
  • 26
  • 173
  • 191
1

i wrote a helper for this.

export const preventFormSubmitOnEnter = {
  mounted() {
    let cb = event => {
      if (event) event.preventDefault();
    };
    if (this.$el.nodeName.toLowerCase() === "form") {
      this.$el.onsubmit = cb;
    } else {
      const forms = this.$el.getElementsByTagName("form");
      for (let i = 0; i < forms.length; i++) {
        const form = forms[i];
        if (form) form.onsubmit = cb;
      }
    }
  }
};

Include this mixin in your vue component and it will automagically work.

here is an example (Im using ElementUI):

<template>
  <el-form :model="form" :rules="rules" ref="form">
    <el-form-item prop="reference">
      <el-input v-model="form.reference" placeholder="Your Reference"/>
    </el-form-item>
  </el-form>
</template>

<script>
import { preventFormSubmitOnEnter } from "./util";

export default {
  mixins: [preventFormSubmitOnEnter],
  data() {
    return {
      form: {
        reference: ""
      },
      rules: {
        reference: [{ required: true, message: "Reference is required!" }]
      }
    };
  },
  methods: {
    validate() {
      return new Promise((resolve, reject) => {
        this.$refs.form.validate(valid => {
          this.$emit("on-validate", valid, this.form);
          resolve(valid);
        });
      });
    },
    validateField(prop) {
      this.$refs.form.validateField(prop);
    }
  }
};
</script>
Stefan Quy
  • 21
  • 5
1

This works

 <input type="text" class="form-control" v-model="get_user" @keydown.enter.prevent = "">
medo-mi
  • 11
  • 2