196

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?

1
  • 1
    I see no form in your fiddle? Commented Mar 22, 2017 at 13:07

9 Answers 9

275

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/[email protected]/dist/vue.js"></script>

<div id="app">
  <input v-on:keyup.enter="onEnter" />
  <h1>{{ msg }}</h1>
</div>

Sign up to request clarification or add additional context in comments.

5 Comments

This gave me the hint I needed. With Buefy I needed to add native for b-input: v-on:keyup.native.enter="onEnter"
You can also use @keyup.enter="doSomething"
v-on:keyup.native.enter="onEnter" is only valid with components not on button.
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).
buefy input and chrome I needed @keydown.enter.native="doSomething" github.com/bootstrap-vue/bootstrap-vue/issues/…
88

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/[email protected]/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>

1 Comment

I had to modify this to `@keyup.native="validateEmailAddress" for it to work with my setup in vue-cli 3
47

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()" />

3 Comments

Is there a site that lists the mapping between characters and numbers (like 50 and @)? I couldn't find it in the Vue documentation.
can i use multiple keys? something like @keydown.1.2 ?
Yes, <input @keyup.50="atPress" @keyup.13="atPress" />
42

This event works to me:

@keyup.enter.native="onEnter".

Comments

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>

1 Comment

Is there a site that lists the mapping between characters and numbers (like 50 and @)? I couldn't find it in the Vue documentation
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.

Comments

10

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" />

Comments

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
});

Comments

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.