Vue.Draggable
Vue.Draggable copied to clipboard
How can i set a selected value without using the mouse (programmatically, on init) ?
Currently, i am trying to select an item of the draggable-list programmatically / manually (without the usage of the mouse).
This behaviour is important, because i want to make a pre-selection when the draggable-component is loaded. I wanted to use the "vuedraggable-multi" Fork (check #744 or https://github.com/divinespear/Vue.Draggable ) as well, which is based on this repository. This feature would allow me to select multiple elements for the drag-and-drop feature. I already tested the #744 and it works for me very well - sad to see that it is not merged yet.
I have read, that the "MultiDrag.singleton.utils.select()"-Method is the way to go for this, but my current Implementation does not contain this singleton (MultiDrag.singleton is undefined when i am importing MultiDrag). This link describes how it should have worked: https://www.fabiofranchino.com/log/add-programmatically-a-draggable-element-in-vuedraggable-with-sortable/
I can set the styling/css-class for the selected element manually, but this has no effect on the internal selection of the vueDraggable-component.
Jsfiddle link
N/A, since the feature does not exist yet afaik.
Relevant code-parts:
import { defineComponent, onMounted } from '@vue/composition-api';
import VueDraggable from 'vuedraggable';
import {Sortable, MultiDrag} from "sortablejs";
if (!MultiDrag.singleton) {
console.log("singleton should exist, when using vuedraggable - but it doesn't");
MultiDrag.singleton = new MultiDrag();
Sortable.mount(MultiDrag.singleton);
}
export default defineComponent({
name: 'MyPage',
components: {
draggable: VueDraggable
},
setup(_, ctx) {
...
onMounted(async () => {
// try to select a vuedraggable-item, when the items are loaded via API-call
const el = ctx.refs.draggablelist.$el.querySelector(".selected");
// the following line doesn't change the internal state of the draggable-list
MultiDrag.singleton.utils.select(el);
}
}
});
Step by step scenario
- Open up VueDraggable and try to set the list-selection via javascript.
Current Solution
N/A - no method currently available to select items programmatically.
When importing MultiDrag from SortableJS ( import {Sortable, MultiDrag } from "sortablejs";
), then the MultiDrag.singleton-field is undefined.
Expected Solution
- Expose the "MultiDrag.singleton.utils"-Methods from within VueDraggable, so that the selection can be done programmatically.
- If there are other methods for the item-selection, then expose these as well.
- Ideally, i can pass an Index/key of the listitem and the corresponding element is then added to the selection
Can you help me with this? That would be great :-) If you can point me to the solution, i also can do a PR if desired.
fyi @David-Desmaisons @divinespear
I have found a work-around with sortable, my stack is::
{
"vue": "^2.6.11",
"vuetify": "^2.4.0",
"sortablejs": "^1.14.0",
}
My test blade file is as shown below. See how I use Vue's $refs to trigger a selection to 2 items programmatically:
<template>
<div class="fluid container">
<v-btn @click="initDraggable" depressed dark>CLICK TO SELECT</v-btn>
<v-row class="ma-7">
<v-col cols="12">
<div id="list" class="list-group">
<div class="list-group-item" ref="my-btn1">Item 1</div>
<div class="list-group-item" ref="my-btn2">Item 2</div>
<div class="list-group-item" ref="my-btn3">Item 3</div>
<div class="list-group-item" ref="my-btn4">Item 4</div>
<div class="list-group-item" ref="my-btn5">Item 5</div>
<div class="list-group-item" ref="button6">Item 6</div>
<div class="list-group-item" ref="button7">Item 7</div>
</div>
</v-col>
</v-row>
</div>
</template>
<script>
import { Sortable, MultiDrag } from 'sortablejs';
Sortable.mount(new MultiDrag());
export default {
name: "hello",
data() {
return { };
},
methods: {
initDraggable() {
let list = document.getElementById('list');
Sortable.create(list, {
group: 'shared',
multiDrag: true,
selectedClass: "selected",
animation: 250
});
Sortable.utils.select(this.$refs.button6);
Sortable.utils.select(this.$refs.button7);
},
},
mounted() {
this.initDraggable();
Sortable.utils.select(this.$refs.button6);
Sortable.utils.select(this.$refs.button7);
}
};
</script>
<style>
.selected {
background-color: #f9c7c8 !important;
border: solid red 1px !important;
z-index: 1 !important;
}
.list-group {
min-height: 20px;
}
.list-group-item {
cursor: move;
}
.list-group-item i {
cursor: pointer;
}
</style>
with this approach you can successfully have a single/multi-select capability done programmatically on button clock/or page load