On a page I have a Vuetify v-form
/v-text-field
. Users can type a query in to this form and press Enter
to update the page.
Sometimes the query is erroneous and a v-dialog
modal pops up to explain the error. It's a complex error and can't just be packed in the rules
attribute of the v-text-field
.
The problem: when the modal is dismissed, the v-text-field
is no longer focused and requires a click before it can be used again. This interrupts the user and requires a shift from keyboard to mouse and back.
What is Vue best practice for re-focusing on the input that triggered the modal?
I can think of one idea it doesn't feel Vue-ish: put a ref
on the v-text-field
and watch the dialog
data property. If dialog
becomes false
, call this.$refs.input.focus()
. However, this seems like the old-fashioned, imperative (not reactive) way to do it. For example:
<template>
<v-form v-model='valid' @submit.prevent='submit'>
<v-text-field
placeholder="Search..."
v-model="query"
:rules="[foo]"
ref='input'
autofocus
></v-text-field>
<v-dialog
v-model="dialog"
@keydown.esc='dialog = false'
>
{{ someErrorMessage }}
</v-dialog>
</v-form>
</template>
// Vue instance
export default {
data: function() {
return {
dialog: false,
query: "",
valid: false
}
},
...
watch: {
// Focus on query after dismissing an error
dialog(newState) {
if (!newState) {
this.$refs.input.focus();
}
}
},
methods: {
foo(value) {
// ... validate value
},
submit(e) {
if (!this.valid) {
this.dialog = true;
return;
}
}
}
}
In the dialog element, I'd probably call a method instead of directly changing
dialog
to false. Then in that method, I'd add focus to the textarea with some plain old javascript.