I have a total of 5 textfields made by using v-text-field. i have give autofocus to textfield 3. how can i change my cursor position in other text fields with the help of arrow keys. i have provided the code below which gives the output of the below image but there is no movement of the cursor when we hit arrow keys.
<script>
export default {
data() {
return {
currentItem: 3,
};
},
mounted() {
document.addEventListener("keyup", this.nextItem);
},
methods: {
nextItem(event) {
if (event.keyCode == 38 && this.currentItem > 1) {
this.currentItem -= 2;
} else if (event.keyCode == 40 && this.currentItem < 6) {
this.currentItem = 2;
} else if (event.keyCode == 37 && this.currentItem < 6) {
this.currentItem -= 1;
} else if (event.keyCode == 39 && this.currentItem < 6) {
this.currentItem = 1;
}
},
},
};
</script>
<template>
<div>
<v-container>
<div @keyup="nextItem">
<v-row>
<v-col cols="12" align-self="center">
<v-text-field label="1st" id="1"></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="3">
<v-text-field
label="2nd"
id="2"
placeholder="Placeholder"
></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="3">
<v-text-field
autofocus
label="3rd"
id="3"
placeholder="Placeholder"
></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="3">
<v-text-field
label="4th"
id="4"
placeholder="Placeholder"
></v-text-field>
</v-col>
<v-col cols="12" align-self="center">
<v-text-field label="5th" id="5"></v-text-field>
</v-col>
</v-row>
</div>
</v-container>
</div>
</template>
CodePudding user response:
that requires manual DOM interaction to me.
set a ref on each field:
<v-text-field ref="first />
Accessing it via this.$refs.first will return you the component instance.
Accessing the component element via this.$refs.first.$el will return you the <div> containing the whole component's element (not the exact template but you get the point):
<div >
<div>
<div>
<input>
</div>
</div>
</div>
You only want the input. You can do:
const input = this.$refs.first.$el.querySelector('input')
Or, since Vuetify already set a ref for the input, you can just do:
const input = this.$refs.first.$refs.input
Then just focus it yourself:
input.focus()
Alternatively, you can also try calling the focus method declared on <VTextField>:
this.$refs.first.focus();
Docs regarding $refs and $el: https://vuejs.org/v2/api/#Instance-Properties
Vuetify source code reference for VTextField's $refs.input: https://github.com/vuetifyjs/vuetify/blob/v2.6.3/packages/vuetify/src/components/VTextField/VTextField.ts#L415
Vuetify source code reference for VTextField's focus method: https://github.com/vuetifyjs/vuetify/blob/v2.6.3/packages/vuetify/src/components/VTextField/VTextField.ts#L247
CodePudding user response:
You need to interact with the DOM focus event to change the active focus, I add a ref to each input with the name of input-${id}.
On keyup I check the key events and if that input ref exist I change the currentItem property, with that you can remove the >1 and <6 conditionals.
Because you want to change the focus every time the currentItem variable changes, I add a watcher with immediate true removing the unmounted.
Template
<v-container>
<div @keyup="changeFocusInput">
<v-row>
<v-col cols="12" align-self="center">
<v-text-field
label="1st"
id="1"
ref="input-1"
></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="3">
<v-text-field
label="2nd"
id="2"
ref="input-2"
placeholder="Placeholder"
></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="3">
<v-text-field
autofocus
label="3rd"
id="3"
ref="input-3"
placeholder="Placeholder"
></v-text-field>
</v-col>
<v-col cols="12" sm="6" md="3">
<v-text-field
label="4th"
id="4"
ref="input-4"
placeholder="Placeholder"
></v-text-field>
</v-col>
<v-col cols="12" align-self="center">
<v-text-field
label="5th"
id="5"
ref="input-5"
></v-text-field>
</v-col>
</v-row>
</div>
</v-container>
JS
data() {
return {
currentItem: 3,
};
},
watch: {
currentItem: {
handler(value, oldValue) {
if (value !== oldValue) {
this.focusInput(value);
}
},
immediate: true
}
},
methods: {
getInput(id) {
const input = this.$refs[`input-${id}`];
return input;
},
changeFocusInput(event) {
const key_code = {
left: 37,
up: 38,
right: 39,
down: 40
};
let nextItem = this.currentItem;
if (event.keyCode == key_code.up) {
nextItem -= 2;
} else if (event.keyCode == key_code.down) {
nextItem = 2;
} else if (event.keyCode == key_code.left) {
nextItem -= 1;
} else if (event.keyCode == key_code.right) {
nextItem = 1;
}
if (this.getInput(nextItem)) {
this.currentItem = nextItem;
}
},
focusInput(id) {
const input = this.getInput(id);
if (input) {
input.focus();
}
},
},

