Reputation: 711
I am trying to create a sortable list with a delete function using vuejs and jquery ui I have the following results
please check the following jsfiddle
https://jsfiddle.net/reda84/7ojgvwdw/
the delete function is working but once you start to sort the delete dose not work correctly anymore specially for the sorted item and items below it.
if I combine both component in one like the following fiddle it works fine but I don't want that because the original application is more complicated with more complex components and I would like to separate it.
https://jsfiddle.net/reda84/jv7zhz1u/
TLDR: here is the code
var listItem = Vue.extend({
template: '<li class="ui-state-default">{{item.title}} {{item.id}} <span v-on:click="remove(item)"> x </span></li>',
props: {
item: Object
},
methods: {
remove: function(item) {
this.$dispatch('remove-item', item)
}
}
});
var sortableList = Vue.extend({
template: '<ul id="sortable"><list-item v-for="item in list" :item="item" class="ui-state-default"></list-item></ul>',
data: function() {
return {
list: [{ id: 1, title: "Item"},
{ id: 2, title: "Item"},
{ id: 3, title: "Item"}]
}
},
events: {
"remove-item": function(item) {
var index = this.list.indexOf(item)
this.list.splice(index, 1);
}
},
components: {
listItem
},
});
new Vue({
el: 'body',
ready: function() {
$("#sortable").sortable();
$("#sortable").disableSelection();
},
components: {
sortableList
},
});
Upvotes: 2
Views: 2582
Reputation: 20805
It looks like the v-for
and sortable
can't both be directly on a vue component. My guess is that Vue and JQuery conflict when they both try to manage the li
elements.
It works if the component is a child of the v-for
. Here is the updated fiddle, and a working code snippet:
Vue.component('list-item', {
template: '#list-item',
props: {
item: Object
},
methods: {
remove: function (item) {
this.$emit('remove-item', item)
}
}
});
Vue.component('sortable-list', {
template: '#sortable-list',
data: function () {
return {
list: [{
id: 1,
title: "Item"
}, {
id: 2,
title: "Item"
}, {
id: 3,
title: "Item"
}]
}
},
methods: {
"removeItem": function (item) {
var index = this.list.indexOf(item)
this.list.splice(index, 1);
}
}
});
new Vue({
el: '#app',
mounted: function () {
$("#sortable").sortable();
$("#sortable").disableSelection();
}
});
#sortable {
list-style-type: none;
margin: 0;
padding: 0;
width: 60%;
}
#sortable li {
font-family: Arial;
margin: 0 3px 3px 3px;
padding: 0.4em;
padding-left: 1.5em;
font-size: 1.4em;
height: 18px;
}
#sortable li span {
float: right;
cursor: pointer
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.4/vue.js"></script>
<div id="app">
<sortable-list></sortable-list>
</div>
<template id="list-item">
<div class="ui-state-default">
{{item.title}} {{item.id}}
<span v-on:click="remove(item)"> x </span>
</div>
</template>
<template id="sortable-list">
<ul id="sortable">
<li v-for="item in list">
<list-item :item="item"
class="ui-state-default"
@remove-item="removeItem">
</list-item>
</li>
</ul>
</template>
Note: the snippet has been updated to use Vue 2.0 syntax.
Upvotes: 2