180

I have a text field and a button.
By default, this button submits a form when someone presses the Enter key on their keyboard.
When someone is typing in the text field, I want to capture each key pressed. If the key is an @ symbol, I want to do something special.

If the key pressed is the Enter key, I want to do something special as well. The latter is the one giving me challenges. Currently, I have this Fiddle, which includes this code:

new Vue({
  el: '#myApp',
  data: {
    emailAddress: '',
    log: ''
  },
  methods: {
    validateEmailAddress: function(e) {
      if (e.keyCode === 13) {
        alert('Enter was pressed');
      } else if (e.keyCode === 50) {
        alert('@ was pressed');
      }      
      this.log += e.key;
    },
    
    postEmailAddress: function() {
      this.log += '\n\nPosting';
    }
});

In my example, I can't seem to press the Enter key without it submitting the form. Yet, I would expect the validateEmailAddress function to at least fire first so that I could capture it. But, that does not seem to be happening.
What am I doing wrong?

kissu
  • 40,416
  • 14
  • 65
  • 133
user687554
  • 10,663
  • 25
  • 77
  • 138

9 Answers9

249

In vue 2, You can catch enter event with v-on:keyup.enter check the documentation:

https://v2.vuejs.org/v2/guide/events.html#Key-Modifiers

I leave a very simple example:

var vm = new Vue({
  el: '#app',
  data: {msg: ''},
  methods: {
    onEnter: function() {
       this.msg = 'on enter event';
    }
  }
});
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>

<div id="app">
  <input v-on:keyup.enter="onEnter" />
  <h1>{{ msg }}</h1>
</div>
starball
  • 20,030
  • 7
  • 43
  • 238
fitorec
  • 4,257
  • 2
  • 24
  • 18
  • 18
    This gave me the hint I needed. With Buefy I needed to add native for b-input: `v-on:keyup.native.enter="onEnter"` – Turbo Aug 20 '19 at 00:53
  • 9
    You can also use @keyup.enter="doSomething" – Dazzle Dec 23 '19 at 16:27
  • 1
    v-on:keyup.native.enter="onEnter" is only valid with components not on button. – Pushplata Mar 04 '20 at 12:21
  • 1
    Do we always need an input to detect key presses? I'm trying to control a Buefy carousel with the arrows and esc key (when in fullscreen). – Nicke Manarin May 12 '20 at 20:07
  • 1
    buefy input and chrome I needed @keydown.enter.native="doSomething" https://github.com/bootstrap-vue/bootstrap-vue/issues/936#issuecomment-325248549 – Russell Munro Mar 12 '21 at 06:14
83

Event Modifiers

You can refer to event modifiers in vuejs to prevent form submission on enter key.

It is a very common need to call event.preventDefault() or event.stopPropagation() inside event handlers.

Although we can do this easily inside methods, it would be better if the methods can be purely about data logic rather than having to deal with DOM event details.

To address this problem, Vue provides event modifiers for v-on. Recall that modifiers are directive postfixes denoted by a dot.

<form v-on:submit.prevent="<method>">
  ...
</form>

As the documentation states, this is syntactical sugar for e.preventDefault() and will stop the unwanted form submission on press of enter key.

Here is a working fiddle.

new Vue({
  el: '#myApp',
  data: {
    emailAddress: '',
    log: ''
  },
  methods: {
    validateEmailAddress: function(e) {
      if (e.keyCode === 13) {
        alert('Enter was pressed');
      } else if (e.keyCode === 50) {
        alert('@ was pressed');
      }      
      this.log += e.key;
    },
    
    postEmailAddress: function() {
            this.log += '\n\nPosting';
    },
    noop () {
      // do nothing ?
    }
  }
})
html, body, #editor {
  margin: 0;
  height: 100%;
  color: #333;
}
<script src="https://unpkg.com/vue@2.2.4/dist/vue.js"></script>
<div id="myApp" style="padding:2rem; background-color:#fff;">
<form v-on:submit.prevent="noop">
  <input type="text" v-model="emailAddress" v-on:keyup="validateEmailAddress" />
  <button type="button" v-on:click="postEmailAddress" >Subscribe</button> 
  <br /><br />
  
  <textarea v-model="log" rows="4"></textarea>  
</form>
</div>
kissu
  • 40,416
  • 14
  • 65
  • 133
Amresh Venugopal
  • 9,299
  • 5
  • 38
  • 52
42

For enter event handling you can use

  1. @keyup.enter or
  2. @keyup.13

13 is the keycode of enter. For @ key event, the keycode is 50. So you can use @keyup.50.

For example:

<input @keyup.50="atPress()" />
kissu
  • 40,416
  • 14
  • 65
  • 133
Rahul TP
  • 536
  • 5
  • 9
41

This event works to me:

@keyup.enter.native="onEnter".
Nuno Ribeiro
  • 2,487
  • 2
  • 26
  • 29
25

You forget a '}' before the last line (to close the "methods {...").

This code works :

Vue.config.keyCodes.atsign = 50;

new Vue({
  el: '#myApp',
  data: {
    emailAddress: '',
    log: ''
  },
  methods: {
  
    onEnterClick: function() {
     alert('Enter was pressed');
    },
    
    onAtSignClick: function() {
     alert('@ was pressed');
    },
    
    postEmailAddress: function() {
   this.log += '\n\nPosting';
    }
  }
})
html, body, #editor {
  margin: 0;
  height: 100%;
  color: #333;
}
<script src="https://vuejs.org/js/vue.min.js"></script>

<div id="myApp" style="padding:2rem; background-color:#fff;">

  <input type="text" v-model="emailAddress" v-on:keyup.enter="onEnterClick" v-on:keyup.atsign="onAtSignClick" />
  
  <button type="button" v-on:click="postEmailAddress" >Subscribe</button> 
  <br /><br />
  
  <textarea v-model="log" rows="4"></textarea>
</div>
Happyriri
  • 4,295
  • 1
  • 17
  • 28
  • Is there a site that lists the mapping between characters and numbers (like 50 and @)? I couldn't find it in the Vue documentation – BusyProgrammer May 26 '20 at 18:56
17

You can also pass events down into child components with something like this:

<CustomComponent
    @keyup.enter="handleKeyUp"
/>

...

<template>
    <div>
        <input
            type="text"
            v-on="$listeners"
        >
    </div>
</template>

<script>
export default {
    name: 'CustomComponent',

    mounted() {
        console.log('listeners', this.$listeners)
    },
}
</script>

That works well if you have a pass-through component and want the listeners to go onto a specific element.

agm1984
  • 15,500
  • 6
  • 89
  • 113
3

Vue 3

In Vue 3, this code works if you want to listen event enter in input:

<input @keyup.enter="onPressEnter" />

Or maybe you want your event to fire when the key is pressed, rather than when it’s released:

<input @keydown.enter="onPressEnter" />
KitKit
  • 8,549
  • 12
  • 56
  • 82
1

you are missing a closing curly bracket for methods

new Vue({
  el: '#myApp',
  data: {
    emailAddress: '',
    log: ''
  },
  methods: {
    validateEmailAddress: function(e) {
      if (e.keyCode === 13) {
        alert('Enter was pressed');
      } else if (e.keyCode === 50) {
        alert('@ was pressed');
      }      
      this.log += e.key;
    },

    postEmailAddress: function() {
      this.log += '\n\nPosting';
    }
  }//add this closing bracket and everything is fine
});
melvin
  • 11
  • 1
1

This is how you would write it in Vue3 with Composition API.

<script setup>
function callOnEnter() {
  console.log("Enter key pressed");
}
</script>

<template>
  <input type="text" @keyup.enter="callOnEnter" />
</template>

More details are available here: https://vuejs.org/guide/essentials/event-handling.html#key-modifiers

kissu
  • 40,416
  • 14
  • 65
  • 133