I have an input field that gets replaced automatically with a textarea and same content depending on the number of characters the user has entered:
<textarea v-if="myString.length > 20" v-model="myString"/> <input type="text" v-if="myString.length <= 20" v-model="myString"/>
The problem i have is that the focus gets lost when a user enters the 21st character. And thus the user gets irritated because when he types the 22nd character it does not appear in the textarea (no focus). How can i set the focus on the newly rendered textarea then? Problem here is that it gets rendered automatically. Otherwise i could set a ref on the textarea and call focus().
Another issue is the removal of the 21st character and the switch-back from textarea to the input elment.
Advertisement
Answer
You could wrap the textarea
/input
in a component, and use its mounted
hook to call its focus()
, as seen in this component:
<!-- AutoFocusedInput.vue --> <script setup> import { ref, onMounted, computed, nextTick } from 'vue' const input = ref() onMounted(async () => { await nextTick() input.value.focus() }) const props = defineProps({ modelValue: String, textarea: Boolean, }) const comp = computed(() => (props.textarea ? 'textarea' : 'input')) </script> <template> <component :is="comp" ref="input" v-bind="$attrs" :value="modelValue" @input="$emit('update:modelValue', $event.target.value)" /> </template>
<AutoFocusedInput textarea v-if="myString.length > 20" v-model="myString" /> <AutoFocusedInput v-else v-model="myString" />
While this is technically possible, this UX is probably not ideal, and you should consider other designs that don’t require focusing input like this (as indicated by @kien_coi_1997).