Thore
Thore

Reputation: 1838

Vue focus on input field when it becomes visible

I've got a title (H1) and an edit button. When pressing the button I want to switch the h1 to an input field. Next I want to focus on the input field but that part isn't working because the reference of the input field is undefined. I've tried a settimeout as workaround but that didn't do the trick.

Anyone with a working solution?

<template>
    <h1 class="text-gray-900 text-2xl font-medium flex items-center">
        <input v-if="isEditing" ref="name" type="text" v-model="role" @keyup.esc="toggleEdit" />
        <span v-else>{{ role }}</span>
        <button @click="toggleEdit">Edit</button>
    </h1>
</template>

<script>
    export default {
        data() {
            return {
                role: 'Admin',
                isEditing: false,
            };
        },
        methods: {
            toggleEdit() {
                this.isEditing = !this.isEditing;
                this.$refs.name.focus();
            },
        },
    };
</script>

Code available: Codesandbox

Upvotes: 1

Views: 1504

Answers (1)

thetailor.de
thetailor.de

Reputation: 312

You just have to wait for the DOM to update. This works:

<template>
  <h1 class="text-gray-900 text-2xl font-medium flex items-center">
    <input
      v-if="isEditing"
      ref="roleName"
      class="text-gray-900 text-2xl font-medium"
      type="text"
      v-model="role"
      @keyup.esc="toggleEditRoleName"
    />
    <span v-else>{{ role }}</span>
    <button
      @click="toggleEditRoleName"
      class="ml-2 h-5 w-5 text-blue-300 cursor-pointer"
      aria-hidden="true"
    >
      Edit
    </button>
  </h1>
</template>

<script>
export default {
  data() {
    return {
      role: "Admin",
      isEditing: false,
    };
  },
  methods: {
    toggleEditRoleName() {
      this.isEditing = !this.isEditing;

      this.$nextTick(() => {
        this.$refs.roleName.focus();
      });
    },
  },
};
</script>

Upvotes: 1

Related Questions