HTML
<span :style="{ display : displayTitle }" @dblclick="showInput()">
{{ node.title }}
</span>
<input :style="{ display : displayTitleInput }" type="text"
@blur="hideInput1" @keydown="hideInput2"
@input="changeTitle(node.id , $event.target.value)"
:value="node.title">
JS
data() {
return {
displayTitle: "inline-block",
displayTitleInput: "none"
};
},
showInput() {
this.displayTitle = "none"
this.displayTitleInput = "inline-block"
},
hideInput1() {
this.displayTitle = "inline-block"
this.displayTitleInput = "none"
},
hideInput2(event) {
if (event.keyCode === 13) {
this.hideInput1()
}
},
HTML is in "v-for" (v-for="node in list"
).
When span element is double-clicked, it gets hidden and the <input>
element is shown.
I want to make it possible to focus on input when it appears.
I tried this but it didn't work.
HTML
<span :style="{ display : displayTitle }" @dblclick="showInput(node.id)">
{{ node.title }}
</span>
<input :ref='"input_" + node.id' :style="{display:displayTitleInput}" type="text"
@blur="hideInput1" @keydown="hideInput2"
@input="changeTitle(node.id , $event.target.value)"
:value="node.title">
JS
showInput(id) {
this.displayTitle = "none"
this.displayTitleInput = "inline-block"
this.$nextTick(this.$refs["input_" + id][0].focus())
},
There was no error on console, but didn't work.
Your primary problem is that $nextTick
takes a callback function but you are executing
this.$refs["input_" + id][0].focus()
immediately. You could get your code working correctly with
this.$nextTick(() => {
this.$refs["input_" + id][0].focus()
})
However, I think you'll run in to further problems and your code can be made much simpler.
One problem you'll find is that all your node inputs will become visible when double-clicking on any of them due to your style rules.
You could instead store an "editing" flag somewhere either on the node
or in a separate object.
Below is an example that simplifies your code by...
ref
when used within a v-for
loop, andenter
modifier on your @keydown
event bindingnew Vue({
el: '#app',
data: {
list: [
{id: 1, title: 'Node #1'},
{id: 2, title: 'Node #2'}
],
editing: {}
},
methods: {
showInput(id, index) {
this.$set(this.editing, id, true)
this.$nextTick(() => {
this.$refs.input[index].focus()
})
},
hideInput(id) {
this.editing[id] = false
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js"></script>
<ul id="app">
<li v-for="(node, index) in list">
<span v-show="!editing[node.id]" @dblclick="showInput(node.id, index)">
{{ node.title }}
</span>
<input v-show="editing[node.id]" type="text"
ref="input" :value="node.title"
@blur="hideInput(node.id)" @keydown.enter="hideInput(node.id)">
</li>
</ul>