knockout-sortable not only provides a sortable
-binding, but also a droppable
-binding. These can be used in combination to get your desired result.
Your container keeps the sortable
-binding, but each item in the list also gets a droppable
-binding, making them a valid target for movement.
When the droppable
-binding on one of these items is triggered, you have a reference to both the item that's being moved and a reference to the item it's being moved onto.
From there you can do whatever you want, for example, you could remove the item being dragged from the parent container and merge it with the item being dragged onto.
The snippet below demonstrates the combination of sortable
and draggable
:
var Item = function(description) {
var self = this;
self.description = ko.observable(description);
self.dropTo = function(droppedElement) {
console.log("Drop target: " + self.description());
console.log("Dropped element: " + droppedElement.description());
};
};
var ViewModel = function() {
var self = this;
self.items = ko.observableArray([
new Item("Item1"),
new Item("Item2"),
new Item("Item3"),
new Item("Item4")
]);
self.dropTo = function(arg1) {
console.log(this);
console.log(arg1);
};
};
ko.applyBindings(new ViewModel());
.container {
background-color: #999;
padding: 4px;
}
.item {
background-color: #ccc;
margin: 4px;
padding: 4px;
}
<script src="https://cdnjs.cloudflare.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.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout-sortable/1.1.0/knockout-sortable.min.js"></script>
<div class="container" data-bind="sortable: items">
<div class="item" data-bind="text: description, droppable: { data: dropTo }"></div>
</div>