nested refs

by Jim Baldwin

HTML

<script src="https://cdn.jsdelivr.net/sortable/1.4.2/Sortable.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.13.1/lodash.min.js"></script>
<script src="https://cdn.rawgit.com/David-Desmaisons/Vue.Draggable/master/dist/vuedraggable.min.js"></script>
<div id="main">
    <div v-for="(task, index) in flatten(taskList)">
        <input :ref="ref(index)" type="text" v-model="task.taskName" @keydown.up="arrowPress(index)">
    </div>
</div>

JavaScript

var vm = new Vue({
    el: "#main",
    data: {
        taskList: [{
            taskName: "Number One"
        }, {
            taskName: "Number Two",
            children: [{
                taskName: "Child One"
            }, {
                taskName: "Child due"
            }]
        }, {
            taskName: "Number Three"
        }]
    },
    created() {},
    methods: {
        flatten(tasks) {
            return tasks.reduce((flat, task) => {
                if (task.children) {
                    return flat.concat(task).concat(this.flatten(task.children));
                }
                return flat.concat(task);
            }, []);
        },
        ref(index) {
            return 'inputField' + index.toString().padStart(4, '0');
        },
        arrowPress(parent, child) {
            let refs = Object.keys(this.$refs).filter(key => key.indexOf('inputField') === 0).sort();
            let i = refs.indexOf(this.ref(parent, child));
            i = Math.max(i - 1, 0);
            let prevRef = refs[i];
            this.$nextTick(() => this.$refs[prevRef][0].focus());
        }
    }
});