Vue.js + Sortable TaskApp
Goal: Sort and update position through AJAX
by sutherland
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.16/vue.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/Sortable/1.4.2/Sortable.min.js"></script>
<div id="app">
<h1>{{ title | uppercase }}</h1>
<div id="task-row" v-sortable.ul="tasks">
<ul class="row col-xs-12" v-for="task in tasks" track-by="$index">
<div class="box btn-reorder col-xs-1">☰</div>
<div class="box col-xs-1">{{ $index + 1 }}</div>
<div class="box col-xs-4">{{ task.description }}</div>
<div class="box col-xs-3">task.position:
<input class="hidden" v-model="task.position" value="{{ $index + 1 }}">{{ task.position }}</div>
</ul>
</div>
</div>
CSS
body {
font-family: Helvetica Neue, Arial, sans-serif;
}
.box {
height: 30px;
width: auto;
border: 1px solid grey;
padding-top: 4px;
margin: 5px 5px;
}
.btn-reorder {
font-size: 22px;
padding: 0 5px;
margin-right: 2px;
cursor: pointer;
}
.sortable-ghost {
background: rgba(0, 0, 0, 0.1);
border: 2px dashed $dark-grey;
}
JavaScript
Vue.directive('sortable', {
twoWay: true,
deep: true,
bind: function() {
var that = this;
var options = {
draggable: Object.keys(this.modifiers)[0],
ghostClass: "sortable-ghost", // Class name for the drop placeholder
};
this.sortable = Sortable.create(this.el, options);
console.log('sortable bound!')
this.sortable.option("onUpdate", function(e) {
console.log("update-1");
that.value.splice(e.newIndex, 0, that.value.splice(e.oldIndex, 1)[0]);
that.value.forEach(function(task, index) {
task.position = index + 1;
});
});
this.onUpdate = function(value) {
console.log("update-3");
that.value = value;
}
},
update: function(value) {
console.log("update-2");
console.log(value);
this.onUpdate(value);
}
});
var app = new Vue({
el: '#app',
data: {
title: 'Tasks',
tasks: [{
description: 'One task',
position: '1'
}, {
description: 'Another task',
position: '2'
}, {
description: 'A third task',
position: '2'
}]
}
})