I'm trying to implement a slack like feature to send a message only when pressing exact enter (without shift pressed)
Considering this vue template <textarea type="text" v-model="message" @keyup.enter.exact="sendMessage($event)"></textarea> with this component
export default { name: 'Typing', data() { return { message: null } }, methods: { sendMessage(e) { // e.stopPropagation() and e.preventDefault() have no impact this.$socket.emit('message', { text: this.message }); console.log(this.message); // Print the message with another '\n' at the end due to textarea default behavior } } } Does anyone has an idea of how I can avoid having the last '\n' without using a regex to delete it before sending it to the backend (which I think will be dirty) ?
Thank you
PS : I'm pretty new to VueJS stack and hope that my question is not obvious
EDIT: This question is similar but the proposed solution is not working
<textarea type="text" v-model="message" @keyup.enter.exact="sendMessage($event)" > </textarea> The code calls the sendMessage method on the keyup event of the Enter key. The keyup event is fired after the key has been released. Therefore the code is calling the method after the key has been pressed, after the default behaviour of the key run (entering a newline) and after the key has been released. preventDefault will not prevent the problem as the behaviour trying to be prevented has already occurred, before the keyup event.
As we have identified the following:
keyup event is fired after the default behaviour has already occurred.The solution is to prevent the default behaviour on the keydown event and call the method on the keyup event.
Note: it is important to only call the method on the
keyupevent to avoid multiple calls if the user holds down the key.
<textarea v-model="value" @keydown.enter.exact.prevent @keyup.enter.exact="send" @keydown.enter.shift.exact="newline" > </textarea> A method which appends a newline to the textarea value can be called when the Enter+Shift combination is pressed.
Below is a snippet demonstrating all the behaviours described in the solution.
new Vue({ template: ` <div> <textarea v-model="value" @keydown.enter.exact.prevent @keyup.enter.exact="send" @keydown.enter.shift.exact="newline" > </textarea> </div> `, data: { value: '', }, methods: { newline() { this.value = `${this.value}\n`; }, send() { console.log('========'); console.log(this.value); console.log('========'); }, }, }).$mount('#root'); <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width"> </head> <body> <div id="root"></div> <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.min.js"></script> </body> </html> If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With