vue.dragable.for
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>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/2.3.1/vuex.js"></script>
<div id="main">
{{gDocument}}
<h1>Vue Dragable</h1>
<div v-if="showDialog">
<div>{{placeholder.type}}: </div>
<span>{{placeholderText[placeholder.type]}}: </span>
<input v-model="placeholder.value" />
<button v-on:click="confirmAdd()">OK</button>
<button v-on:click="cancelAdd()">Cancel</button>
</div>
<div class="drag">
<draggable
id="list1"
class="dragArea"
:list="list1"
:move="checkMove"
:options="{group:{name:'people', pull:'clone', put:false }}">
<div
class="select-item"
v-for="(element, index) in list1" >
Add {{element.type}}
</div>
</draggable>
<draggable
id="list2"
class="dragArea"
:options="{group:'people'}"
@change="afterAdd"
:list="gDocument">
<div
class="document-item"
v-for="(element, index) in gDocument"
:key="index">
<h3>{{element.type}}</h3>
<img v-if="element.type==='image'" v-bind:src="element.value"/>
<div>{{element.value}}</div>
</div>
</draggable>
</div>
<!-- <div class="normal">
<h2>List 1 v-for</h2>
<div>
<div v-for="(element, index) in list1" :key="index">{{element.name}}</div>
</div>
<h2>List 2 v-for</h2>
<div>
<div v-for="(element, index) in list2" :key="index">{{element.name}}</div>
</div>
</div>
<a href="index.html">See basic example</a>
<a href="Two_Lists.html">See 2 lists example</a>
<a href="Two_Lists.html">See 2 lists example</a> -->
</div>
CSS
.normal {
background-color: grey;
}
.drag {
display: flex;
background-color: green;
}
.dragArea {
border: solid 1px black;
background-color: grey;
min-height: 10px;
}
.document-item, .select-item {
background-color: white;
border: solid 1px black;
margin: 8px 8px 8px 8px;
}
JavaScript
const { mapGetters } = Vuex
const store = new Vuex.Store({
state: {
itemTypes: [{ type:"table", id:1 }, {type:"image", id:2}, {type:"paragraph", id:3}],
document: [{ type: 'paragraph', value: 'sampleText1' }, { type: 'image', value: 'http://via.placeholder.com/350x150' }, { type: 'paragraph', value: 'sampleText2' }]
},
getters: {
gDocument: (state) => state.document
},
mutations: {
APPEND_TO_DOCUMENT: (state, input) => {
state.document.splice(input.newIdx, 0, {
type: input.type,
value: input.value
})
state.document = state.document.filter((item) => item.value);
},
CANCEL_EDIT_DOCUMENT: (state) => {
state.document = state.document.filter((item) => item.value);
}
},
});
var vm = new Vue({
el: "#main",
store,
data: {
list1: [{ type:"table", id:1 }, {type:"image", id:2}, {type:"paragraph", id:3}],
showDialog: false,
placeholderText: {
table: 'Cell value',
image: 'Link',
paragraph: 'Text'
},
placeholder: {
type: '',
value: '',
newIdx: 0
}
},
computed: Object.assign({
// add computed properties here
// exmaple: {
// get () { return 'example'},
// set (val) { this.$store.commit('sample', val) }
// }
}, mapGetters([
'gDocument'
])),
methods:{
confirmAdd() {
this.$store.commit('APPEND_TO_DOCUMENT', this.placeholder)
this.placeholder = {}
this.showDialog = false
},
cancelAdd() {
this.$store.commit('CANCEL_EDIT_DOCUMENT')
this.placeholder = {}
this.showDialog = false
},
afterAdd(evt) {
this.placeholder = {
type: evt.added.element.type,
value: '',
newIdx: evt.added.newIndex
}
this.showDialog = true
},
checkMove(evt) {
this.futureIndex = evt.draggedContext.futureIndex;
return true;
}
}
});