Reputation: 1432
I have two event listeners on an input component(@input and @keyup.delete). I am using the @input listener to detect keys and handle their usage accordingly, while I want to also detect when a user taps the delete or backspace button, so that I can change the index in a pin field.
<template>
<div>
...
<input
...
:value="value"
@keyup.delete="$emit('delete-or-backspace-key-pressed')"
@input="$emit('input', $event.target.value)"
...
/>
...
</div>
</template>
<BaseInputField
...
@input="handleInput"
@delete-or-backspace-key-pressed="handleDeletion"
...
/>
The problem is that pressing the del
or backspace
button also triggers the @input
event, and it's messing with my implementation.
I would appreciate help on preventing this behaviour without the use of Keycodes
, as according to Vue documentation, they are deprecated and may not work with newer browsers.
Upvotes: 4
Views: 19373
Reputation: 1493
Just change the BaseInputField.vue
to the following:
<template>
<input
:value="value"
@keyup.delete="triggerDBKey"
@input="triggerInput"
@paste="triggerPaste"
/>
</template>
<script>
export default {
name: 'BaseInputField',
props: {
value: {type: String, default: ''}
},
data() {
return {
originalValue: this.value
}
},
methods: {
triggerInput(e) {
if (this.originalValue.length > 0 && this.originalValue.length > e.target.value.length) return
this.originalValue = e.target.value
this.$emit('input', e.target.value)
},
triggerDBKey(e) {
if (e.target.value === '') {
this.originalValue = ''
}
this.$emit('delete-or-backspace-key-pressed')
},
triggerPaste(e) {
this.$emit('paste')
}
}
}
</script>
Prevent the input event from being triggered by judging the content length before and after editing.
Here is my codesandbox
Upvotes: 2
Reputation: 6853
You can use event.key
instead, but you need to use @keydown
event instead of @input
event.key
value will be "Backspace"
or "Delete"
if you press backspace / del respectively.
And you can do preventDefault
on your handleInput
function to prevent the input value deletion. So instead of passing $event.target.value
, pass the whole $event
object from the input
@keydown="$emit('input', $event)"
and on your handleInput
function:
handleInput(e) {
if (e.key === "Backspace" || e.key === "Delete") {
return e.preventDefault(); // Don't do anything to the input value
}
const value = e.target.value;
// do something with value
}
Demo: https://codesandbox.io/s/fast-snowflake-xpwqm?file=/src/App.vue
Upvotes: 6