user687554
user687554

Reputation: 11151

Handling Enter Key in Vue.js

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?

Upvotes: 194

Views: 418603

Answers (9)

KitKit
KitKit

Reputation: 9583

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

Upvotes: 10

fitorec
fitorec

Reputation: 4795

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>

Upvotes: 273

kissu
kissu

Reputation: 46814

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

Upvotes: 1

Rahul TP
Rahul TP

Reputation: 584

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

Upvotes: 46

Amresh Venugopal
Amresh Venugopal

Reputation: 9549

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>

Upvotes: 86

melvin
melvin

Reputation: 11

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

Upvotes: 1

agm1984
agm1984

Reputation: 17178

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.

Upvotes: 17

Nuno Ribeiro
Nuno Ribeiro

Reputation: 2565

This event works to me:

@keyup.enter.native="onEnter".

Upvotes: 41

Happyriri
Happyriri

Reputation: 4443

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>

Upvotes: 25

Related Questions